---
title: "Migrating from KrakenD to Zuplo: Configuration Mapping and Architecture Translation"
description: "A practical guide to migrating from KrakenD to Zuplo — covering krakend.json translation, plugin-to-policy mapping, and a phased migration plan."
canonicalUrl: "https://zuplo.com/learning-center/migrating-from-krakend-to-zuplo"
pageType: "learning-center"
authors: "nate"
tags: "API Gateway, Tutorial"
image: "https://zuplo.com/og?text=Migrating%20from%20KrakenD%20to%20Zuplo"
---
KrakenD is a strong choice for teams that want a stateless, high-performance API
gateway with a declarative configuration model. But as API programs grow, teams
hit a ceiling: custom logic requires Go plugins or Lua scripts, Enterprise
Edition feature gates lock critical capabilities behind paid licensing, and
self-hosting means your platform team owns deployment, scaling, and patching.

If your team has outgrown KrakenD's declarative-only model and is looking for a
managed, programmable API gateway, this guide walks you through every step of
migrating from KrakenD to Zuplo.

## Table of Contents

1. [Why Teams Migrate from KrakenD](#why-teams-migrate-from-krakend)
2. [Architecture Comparison](#architecture-comparison)
3. [Configuration Translation](#configuration-translation)
4. [Plugin and Middleware Mapping](#plugin-and-middleware-mapping)
5. [Authentication Migration](#authentication-migration)
6. [Rate Limiting and Caching Migration](#rate-limiting-and-caching-migration)
7. [Custom Plugin Migration](#custom-plugin-migration)
8. [Developer Portal Migration](#developer-portal-migration)
9. [CI/CD and GitOps](#cicd-and-gitops)
10. [Step-by-Step Migration Playbook](#step-by-step-migration-playbook)
11. [Enterprise Edition Feature Parity](#enterprise-edition-feature-parity)
12. [Frequently Asked Questions](#frequently-asked-questions)
13. [Next Steps](#next-steps)

## Why Teams Migrate from KrakenD

KrakenD's audience is config-as-code engineers who value a stateless,
declarative gateway. That philosophy works well until it doesn't. Here are the
pain points that drive teams to explore alternatives:

- **The declarative-only ceiling** — KrakenD processes all configuration from a
  single JSON file loaded at startup. When you need imperative logic —
  conditional routing, dynamic header injection based on request bodies, or
  custom response composition — you're pushed into Go plugins, Lua scripts, or
  CEL expressions. Each has capability trade-offs, and none offers the developer
  experience of a modern language with full IDE support.
- **Self-hosting burden** — KrakenD has no managed cloud offering. Your team
  owns deployment, scaling, patching, and capacity planning. Running KrakenD in
  production means maintaining Docker or Kubernetes infrastructure, handling
  rolling upgrades, and managing TLS certificates — operational work that
  doesn't ship API features.
- **Enterprise Edition feature gates** — API key authentication, OpenAPI
  import/export, tiered rate limiting, basic auth, gRPC support, WebSockets, and
  the AI Gateway are all Enterprise-only features. Teams running production APIs
  face Enterprise licensing decisions for capabilities that most managed
  platforms include by default.
- **Plugin compatibility constraints** — Custom Go plugins must be compiled
  against the exact same build arguments and module version as the target
  KrakenD binary. A KrakenD upgrade can break every custom plugin, forcing
  recompilation and testing across your entire plugin library.
- **No built-in developer portal** — KrakenD does not include a hosted developer
  portal with self-serve API key management. Teams building API products need to
  build or integrate a separate documentation and key management solution using
  tools like Swagger UI or Redoc, adding another system to maintain.

## Architecture Comparison

Understanding the architectural differences helps you plan a clean migration.

### KrakenD's Architecture

KrakenD is a stateless API gateway written in Go, built on the Lura framework (a
Linux Foundation project). A typical deployment involves:

- A **single declarative JSON configuration** (`krakend.json`) loaded at startup
  that defines all endpoints, backends, and middleware
- **Stateless instances** deployed on Docker or Kubernetes — no database, no
  control plane
- **Endpoints** that expose paths to clients, each mapping to one or more
  **backends** (your upstream services)
- **Extra config** blocks for middleware (rate limiting, JWT validation,
  caching, CORS) attached to endpoints or backends
- **Go plugins, Lua scripts, or CEL expressions** for custom logic beyond what
  the declarative config supports
- **flexible_config** for templating and splitting configuration using Go
  templates

### Zuplo's Architecture

Zuplo takes a fundamentally different approach:

- **Edge-native deployment** — Your gateway runs across 300+ data centers
  worldwide automatically. There is no single-region deployment to manage or
  scale.
- **OpenAPI-native routing** — Routes are defined in a standard
  `routes.oas.json` file using the OpenAPI specification format, extended with
  `x-zuplo-route` for gateway behavior.
- **TypeScript policies** — Instead of Go plugins or Lua scripts, you write
  policies in TypeScript with full IDE support, type safety, and access to npm
  packages.
- **Git-native CI/CD** — Every configuration change is version-controlled. Push
  to GitHub, and your gateway deploys to the edge automatically. Every branch
  gets its own isolated preview environment.
- **Fully managed** — No Docker containers, no Kubernetes clusters, no capacity
  planning. Zuplo handles all infrastructure, scaling, and updates.
- **Built-in developer portal** —
  [Auto-generated from your OpenAPI spec](https://zuplo.com/docs/dev-portal/introduction),
  with API key management and API explorer included.

## Configuration Translation

The most important step in migration is translating your `krakend.json` into
Zuplo's route and policy model.

### KrakenD Endpoints → Zuplo Routes

In KrakenD, you define endpoints and backends in `krakend.json`:

```json
{
  "$schema": "https://www.krakend.io/schema/krakend.json",
  "version": 3,
  "endpoints": [
    {
      "endpoint": "/api/users/{id}",
      "method": "GET",
      "backend": [
        {
          "url_pattern": "/users/{id}",
          "host": ["http://user-service:8080"]
        }
      ],
      "extra_config": {
        "auth/validator": {
          "alg": "RS256",
          "jwk_url": "https://auth.example.com/.well-known/jwks.json",
          "issuer": "https://auth.example.com/"
        },
        "qos/ratelimit/router": {
          "max_rate": 60,
          "client_max_rate": 10,
          "strategy": "ip"
        }
      }
    }
  ]
}
```

In Zuplo, the same endpoint is defined in `routes.oas.json` — a standard OpenAPI
file extended with Zuplo configuration:

```json
{
  "paths": {
    "/api/users/{id}": {
      "get": {
        "summary": "Get User by ID",
        "x-zuplo-route": {
          "corsPolicy": "none",
          "handler": {
            "export": "urlRewriteHandler",
            "module": "$import(@zuplo/runtime)",
            "options": {
              "rewritePattern": "http://user-service:8080/users/${params.id}"
            }
          },
          "policies": {
            "inbound": ["jwt-auth", "rate-limit"]
          }
        }
      }
    }
  }
}
```

The corresponding policies are defined in `policies.json`:

```json
{
  "policies": [
    {
      "name": "jwt-auth",
      "policyType": "open-id-jwt-auth-inbound",
      "handler": {
        "export": "OpenIdJwtInboundPolicy",
        "module": "$import(@zuplo/runtime)",
        "options": {
          "issuer": "https://auth.example.com/",
          "jwkUrl": "https://auth.example.com/.well-known/jwks.json"
        }
      }
    },
    {
      "name": "rate-limit",
      "policyType": "rate-limit-inbound",
      "handler": {
        "export": "RateLimitInboundPolicy",
        "module": "$import(@zuplo/runtime)",
        "options": {
          "rateLimitBy": "ip",
          "requestsAllowed": 10,
          "timeWindowMinutes": 1
        }
      }
    }
  ]
}
```

Key differences to note:

- **OpenAPI-native** — Zuplo routes are standard OpenAPI paths. You can import
  an existing OpenAPI spec and add `x-zuplo-route` extensions.
- **Policies replace extra_config** — Instead of attaching middleware via
  `extra_config` blocks, you reference named policies in your route config.
- **Everything in Git** — Both `routes.oas.json` and `policies.json` are files
  in your repository. There is no startup config reload — push to Git and Zuplo
  deploys automatically.

### KrakenD Backends → Zuplo Handlers

KrakenD's `backend` array defines where requests are forwarded. Each backend can
specify response manipulation (allow/deny lists, field mapping, group names).

In Zuplo, backend routing uses handlers:

- **[URL Rewrite Handler](https://zuplo.com/docs/handlers/url-rewrite)** —
  Rewrites the incoming URL using template interpolation with path parameters,
  query strings, and environment variables.
- **[URL Forward Handler](https://zuplo.com/docs/handlers/url-forward)** —
  Forwards the request to a backend, preserving the request path.

For KrakenD's response manipulation features (allow lists, field mapping,
grouping), use Zuplo's
[Custom Code Outbound Policy](https://zuplo.com/docs/policies/custom-code-outbound)
to transform responses in TypeScript.

### KrakenD flexible_config → Git + Environment Variables

KrakenD's `flexible_config` lets you split `krakend.json` into templates and
partials using Go template syntax. In Zuplo, this is handled natively:

- **Configuration is already split** — Routes live in `routes.oas.json`,
  policies live in `policies.json`, and custom code lives in `modules/`.
- **Environment variables** — Referenced as `$env(VARIABLE_NAME)` in
  configuration files or imported from `@zuplo/runtime` in TypeScript.
- **Git branching** — Each branch gets its own isolated environment, replacing
  the need for environment-specific config templates.

## Plugin and Middleware Mapping

One of the biggest questions during migration is: "What replaces my KrakenD
middleware?" Below is a mapping of KrakenD's most common features to their Zuplo
equivalents.

### Authentication

- **auth/validator (JWT)** →
  [JWT Auth Policy (OpenID)](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
  — Validates JWT tokens from any OpenID-compliant provider. Works with Auth0,
  Okta, Azure AD, and others out of the box.
- **auth/api-keys** (Enterprise) →
  [API Key Authentication](https://zuplo.com/docs/policies/api-key-inbound) —
  Zuplo's built-in API key policy includes a managed key service with
  self-service key management through the developer portal. Available on all
  plans — no Enterprise gate.
- **auth/basic** (Enterprise) →
  [Basic Auth Policy](https://zuplo.com/docs/policies/basic-auth-inbound) —
  Built-in support for HTTP Basic authentication.
- **auth/signer (JWT signing)** →
  [Custom Code Policy](https://zuplo.com/docs/policies/custom-code-inbound) —
  Write token signing logic in TypeScript using standard crypto libraries.

### Traffic Control

- **qos/ratelimit/router** →
  [Rate Limiting Policy](https://zuplo.com/docs/policies/rate-limit-inbound) —
  Supports per-user, per-IP, per-API-key, or custom attribute-based rate limits.
  No Redis or separate database needed.
- **qos/ratelimit/proxy** →
  [Rate Limiting Policy](https://zuplo.com/docs/policies/rate-limit-inbound) —
  Apply rate limits at the route level to control traffic to specific backends.
- **qos/circuit-breaker** →
  [Custom Code Policy](https://zuplo.com/docs/policies/custom-code-inbound) —
  Implement circuit breaker patterns in TypeScript with full control over
  failure thresholds and recovery logic.

### Request and Response Transformation

- **modifier/martian (DSL)** →
  [Set Headers Policy](https://zuplo.com/docs/policies/set-headers-inbound) +
  [Custom Code Policy](https://zuplo.com/docs/policies/custom-code-inbound) —
  Combine built-in header policies with custom TypeScript transformation.
- **modifier/body-generator** (Enterprise) →
  [Custom Code Policy](https://zuplo.com/docs/policies/custom-code-inbound) —
  Transform request bodies in TypeScript with full type safety.
- **modifier/response-body-generator** (Enterprise) →
  [Custom Code Outbound Policy](https://zuplo.com/docs/policies/custom-code-outbound)
  — Transform response bodies before they reach the client.
- **modifier/lua** →
  [Custom Code Policy](https://zuplo.com/docs/policies/custom-code-inbound) —
  Replace Lua scripts with TypeScript policies. TypeScript gives you IDE
  autocomplete, type checking, and access to the npm ecosystem.

### Validation

- **validation/json-schema** →
  [Request Validation Policy](https://zuplo.com/docs/policies/request-validation-inbound)
  — Validates request bodies, query parameters, path parameters, and headers
  against your OpenAPI schema definitions automatically.

### Security

- **security/cors** →
  [Custom CORS Policy](https://zuplo.com/docs/programmable-api/custom-cors-policy)
  — Configure allowed origins, methods, and headers per route.
- **security/bot-detector** →
  [Bot Detection Policy](https://zuplo.com/docs/policies/bot-detection-inbound)
  (Enterprise add-on) — Bot scoring and detection for identifying automated
  traffic.

### Caching

- **qos/http-cache** → Zuplo runs on a global edge network with built-in caching
  support. Configure cache headers on your responses, and Zuplo's edge network
  handles caching automatically.

## Authentication Migration

Authentication is typically the most critical part of any gateway migration.
Here is how to translate each KrakenD auth mechanism.

### JWT Authentication

KrakenD's `auth/validator` validates JWT tokens using JWKS endpoints. Zuplo's
[JWT Auth Policy](https://zuplo.com/docs/policies/open-id-jwt-auth-inbound)
provides the same functionality with a simpler configuration model.

**KrakenD (`krakend.json` extra_config):**

```json
{
  "extra_config": {
    "auth/validator": {
      "alg": "RS256",
      "jwk_url": "https://your-tenant.auth0.com/.well-known/jwks.json",
      "issuer": "https://your-tenant.auth0.com/",
      "audience": ["https://api.example.com"]
    }
  }
}
```

**Zuplo (`policies.json`):**

```json
{
  "name": "jwt-auth",
  "policyType": "open-id-jwt-auth-inbound",
  "handler": {
    "export": "OpenIdJwtInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "issuer": "https://your-tenant.auth0.com/",
      "audience": "https://api.example.com",
      "jwkUrl": "https://your-tenant.auth0.com/.well-known/jwks.json"
    }
  }
}
```

If you use provider-specific JWT configurations, Zuplo offers dedicated policies
for [Auth0](https://zuplo.com/docs/policies/auth0-jwt-auth-inbound),
[Clerk](https://zuplo.com/docs/policies/clerk-jwt-auth-inbound),
[Okta](https://zuplo.com/docs/policies/okta-jwt-auth-inbound),
[Firebase](https://zuplo.com/docs/policies/firebase-jwt-inbound),
[AWS Cognito](https://zuplo.com/docs/policies/cognito-jwt-auth-inbound), and
[Supabase](https://zuplo.com/docs/policies/supabase-jwt-auth-inbound).

### API Key Authentication

KrakenD's API key authentication is an Enterprise-only feature. Zuplo's
[API Key Authentication policy](https://zuplo.com/docs/policies/api-key-inbound)
is available on every plan and includes a complete managed key service:

1. Create consumers with metadata (plan tier, organization, custom attributes)
2. Issue API keys that are automatically validated at the edge
3. Let developers self-manage their keys through the developer portal
4. Access consumer metadata in your policies via `request.user`

To migrate API key consumers, use Zuplo's
[API Key Management API](https://zuplo.com/docs/articles/api-key-api) to
programmatically create consumers and import keys.

### Identity Provider SSO

KrakenD Enterprise supports multiple identity providers per endpoint. Zuplo
supports multiple auth methods per route through
[composite policies](https://zuplo.com/docs/policies/composite-inbound) or
multiple auth policies with the `allowUnauthenticatedRequests` option. See the
[multiple authentication policies guide](https://zuplo.com/docs/articles/multiple-auth-policies)
for configuration details.

## Rate Limiting and Caching Migration

### Rate Limiting

KrakenD offers endpoint-level (`qos/ratelimit/router`) and backend-level
(`qos/ratelimit/proxy`) rate limiting. The Community Edition supports basic rate
limiting, while tiered and Redis-backed rate limiting are Enterprise-only.

Zuplo's
[Rate Limiting Policy](https://zuplo.com/docs/policies/rate-limit-inbound)
provides:

- **Per-user, per-IP, or per-key limiting** — Choose what attribute to rate
  limit by.
- **Custom bucket functions** — Write a TypeScript function to define custom
  rate limit grouping logic (e.g., rate limit by customer tier stored in API key
  metadata).
- **No external dependencies** — Unlike KrakenD's Redis-backed strategy, Zuplo's
  rate limiter works out of the box across all edge locations.
- **Standard 429 responses** — Automatically returns `429 Too Many Requests`
  with appropriate `Retry-After` headers.

#### Dynamic Rate Limiting by Customer Tier

In KrakenD Enterprise, tiered rate limiting requires Enterprise licensing. In
Zuplo, you write a short TypeScript function:

```typescript
import {
  CustomRateLimitDetails,
  ZuploContext,
  ZuploRequest,
} from "@zuplo/runtime";

export function rateLimit(
  request: ZuploRequest,
  context: ZuploContext,
  policyName: string,
): CustomRateLimitDetails | undefined {
  const user = request.user;

  if (user.data.customerType === "premium") {
    return {
      key: user.sub,
      requestsAllowed: 1000,
      timeWindowMinutes: 1,
    };
  }

  return {
    key: user.sub,
    requestsAllowed: 50,
    timeWindowMinutes: 1,
  };
}
```

This runs at the edge with no separate infrastructure required.

### Caching

KrakenD's `qos/http-cache` provides proxy-level response caching. Zuplo runs on
a global edge network where caching is handled at the network layer. Set
appropriate `Cache-Control` headers on your backend responses, and Zuplo's edge
infrastructure caches responses automatically across 300+ locations.

For more granular caching control, use a
[Custom Code Outbound Policy](https://zuplo.com/docs/policies/custom-code-outbound)
to set or modify cache headers before responses reach the client.

## Custom Plugin Migration

If your team has built custom KrakenD plugins in Go or Lua scripts, migrating
them to Zuplo TypeScript policies is usually more straightforward than you might
expect. Zuplo's
[Custom Code Inbound Policy](https://zuplo.com/docs/policies/custom-code-inbound)
lets you write arbitrary request processing logic in TypeScript.

### KrakenD Lua Script vs. Zuplo TypeScript Policy

Here is a side-by-side comparison of a simple header-injection middleware:

**KrakenD (Lua script):**

```lua
function pre_proxy(request)
  request:headers("X-Custom-Header", "my-value")
  request:headers("X-Request-Timestamp", os.time())
end
```

**Zuplo (TypeScript):**

```typescript
import { ZuploContext, ZuploRequest } from "@zuplo/runtime";

export default async function (
  request: ZuploRequest,
  context: ZuploContext,
  options: { headerValue: string },
  policyName: string,
) {
  const newRequest = new ZuploRequest(request);
  newRequest.headers.set("X-Custom-Header", options.headerValue);
  newRequest.headers.set("X-Request-Timestamp", Date.now().toString());
  return newRequest;
}
```

### KrakenD Go Plugin vs. Zuplo TypeScript Policy

Go plugins are KrakenD's most powerful extension mechanism, but they come with
significant constraints: plugins must be compiled against the exact KrakenD
binary version, they require a Go development environment, and debugging is
difficult. A KrakenD upgrade can break every custom plugin.

In Zuplo, the same logic is a TypeScript function with:

- **Full IDE support** — Autocomplete, type checking, and inline documentation
  in VS Code or any TypeScript editor.
- **Standard Web APIs** — Zuplo uses standard `Request`, `Response`, and
  `Headers` objects. If you know the Fetch API, you know how to write Zuplo
  policies.
- **No binary coupling** — TypeScript policies don't need to be recompiled when
  the platform updates.
- **Easier testing** — Unit test your policies like any TypeScript function.

## Developer Portal Migration

KrakenD does not include a built-in hosted developer portal with self-serve API
key management. Teams using KrakenD typically rely on external tools like
Swagger UI, Redoc, or custom-built documentation portals. This means maintaining
a separate system for API documentation, key distribution, and developer
onboarding.

Zuplo's developer portal is built into the platform and
[auto-generated from your OpenAPI spec](https://zuplo.com/docs/dev-portal/introduction).
When you update your routes in `routes.oas.json`, the portal updates
automatically. Features include:

- **Automatic API documentation** — Generated directly from your OpenAPI
  specification.
- **API Explorer** — Developers can test your API directly from the docs.
- **Self-serve API key management** — Consumers sign up, get keys, and manage
  them without your intervention.
- **Custom branding and pages** — Add custom Markdown, MDX, or React pages to
  your portal.
- **Built-in analytics** — Consumers can see their own usage data.

For teams migrating from KrakenD, the developer portal is often the single
biggest capability gain — it replaces a system you would have had to build and
maintain separately.

## CI/CD and GitOps

### KrakenD's Workflow

KrakenD's configuration-as-code approach works well with CI/CD, but teams are
responsible for the full deployment pipeline:

1. Edit `krakend.json` (or templates if using `flexible_config`)
2. Run `krakend check` to validate syntax
3. Build a Docker image or deploy to Kubernetes
4. Roll out new instances with the updated configuration
5. Handle rolling restarts to avoid downtime
6. Manage configuration across multiple environments manually

### Zuplo's Workflow

Zuplo's deployment model is Git-native:

1. Your gateway configuration (`routes.oas.json`, `policies.json`, and custom
   TypeScript modules) lives in a GitHub repository
2. Push to a branch, and Zuplo automatically creates a preview deployment
3. Merge to main, and the production gateway updates across all 300+ edge
   locations
4. Every deployment is immutable and versioned — rollback by reverting a commit
5. Environment variables handle per-environment differences (staging vs.
   production)

There is no Docker image to build, no Kubernetes rollout to manage, and no
configuration reload to coordinate.

## Step-by-Step Migration Playbook

A typical KrakenD-to-Zuplo migration follows three phases.

### Phase 1: Audit and Setup (Week 1)

**Inventory your KrakenD setup:**

- Export or catalog your `krakend.json` (or assembled config if using
  `flexible_config`)
- List all endpoints, backends, and their `extra_config` middleware
- Identify any Go plugins or Lua scripts that need translation
- Document rate limiting, JWT validation, and caching configurations
- Note any Enterprise-only features you depend on

**Set up Zuplo:**

- Create a Zuplo account at [portal.zuplo.com](https://portal.zuplo.com)
- Connect your
  [GitHub repository](https://zuplo.com/docs/articles/source-control)
- Translate KrakenD endpoints to `routes.oas.json` routes
- Configure authentication policies to match your KrakenD auth middleware
- Set up rate limiting policies
- Add environment variables for backend URLs and secrets

### Phase 2: Policy Translation and Testing (Week 2–3)

- Translate Go plugins and Lua scripts to TypeScript policies
- Migrate request/response transformations to Zuplo custom code policies
- Configure the developer portal with your OpenAPI spec
- Test all routes against your backend services
- Validate authentication flows end-to-end
- Run load tests to verify rate limiting behavior
- Review logging and observability configuration

### Phase 3: Parallel Running and Cutover (Week 3–4)

Run Zuplo alongside KrakenD to validate behavior:

1. Deploy your Zuplo project by pushing to your Git repository
2. Set up a [custom domain](https://zuplo.com/docs/articles/custom-domains) for
   your Zuplo gateway
3. Route a subset of traffic to Zuplo using DNS-based routing
4. Compare response behavior between KrakenD and Zuplo
5. Gradually increase traffic to Zuplo as you validate correctness
6. Complete the full cutover once you're confident

**Rollback strategy:**

- **Configuration rollback** — Revert the Git commit and push. The previous
  gateway configuration deploys automatically.
- **DNS rollback** — If you kept KrakenD running during the parallel phase,
  switch DNS back to KrakenD's endpoints.

## Enterprise Edition Feature Parity

Many KrakenD Enterprise-only features are available on every Zuplo plan. Here is
how they map:

### Features Gated Behind KrakenD Enterprise

- **API key authentication** — Available on every Zuplo plan via the
  [API Key Authentication Policy](https://zuplo.com/docs/policies/api-key-inbound).
- **OpenAPI import/export** — Zuplo is OpenAPI-native. Routes are defined in
  OpenAPI format, and the developer portal auto-generates from your spec.
- **Tiered rate limiting** — Zuplo supports
  [custom rate limit functions](https://zuplo.com/docs/policies/rate-limit-inbound)
  that let you implement tiered limits based on consumer metadata.
- **gRPC support** (Enterprise) — Not directly equivalent in Zuplo, which
  focuses on HTTP/REST APIs. If gRPC is a primary requirement, evaluate whether
  Zuplo's HTTP-based approach meets your needs.
- **WebSockets** (Enterprise) — Zuplo supports WebSocket proxying for real-time
  communication use cases via the
  [WebSocket Handler](https://zuplo.com/docs/handlers/websocket-handler)
  (Enterprise).
- **AI Gateway and MCP** (Enterprise) — Zuplo includes an
  [integrated AI Gateway](/ai-gateway) with multi-provider model routing,
  semantic caching, and prompt injection protection. The
  [MCP Gateway](/mcp-gateway) lets you turn any API into a remote MCP server or
  govern third-party MCP servers.

### Managed Deployment

KrakenD is self-hosted only — there is no managed cloud offering. Zuplo provides
[managed dedicated deployment](https://zuplo.com/docs/dedicated/overview) on
AWS, Azure, GCP, Akamai, and other providers with single-tenant isolation,
private networking, and data residency controls. Your team gets production-grade
infrastructure without the operational burden.

### Observability

KrakenD offers OpenTelemetry, Prometheus, Datadog, and other integrations. Zuplo
includes built-in request analytics and supports integrations with
[Datadog, Dynatrace, and other providers](https://zuplo.com/docs/articles/logging)
via log plugins.

## Frequently Asked Questions

### Does Zuplo support KrakenD's declarative API aggregation?

KrakenD excels at declarative API aggregation — merging responses from multiple
backends in parallel. Zuplo supports routing to multiple backends and composing
responses using custom TypeScript logic, but the approach is programmatic rather
than declarative. If backend-for-frontend aggregation is your primary use case,
evaluate whether Zuplo's TypeScript-based approach meets your needs.

### How long does a KrakenD migration take?

For most teams using built-in KrakenD features (JWT validation, rate limiting,
response transformation), migration takes two to four weeks. Teams with custom
Go plugins or extensive Lua scripts should plan for additional time to rewrite
those in TypeScript.

### Do I need to change my backend services?

No. Zuplo proxies requests to your existing backends using the
[URL Rewrite handler](https://zuplo.com/docs/handlers/url-rewrite). Your backend
services do not need any changes — Zuplo forwards requests just like KrakenD
does.

### Can I run Zuplo alongside KrakenD during migration?

Yes. The recommended approach is to run both gateways in parallel during the
cutover phase, using DNS or a load balancer to gradually shift traffic from
KrakenD to Zuplo.

### What replaces KrakenD's flexible_config?

KrakenD's `flexible_config` lets you template and split `krakend.json` using Go
templates. In Zuplo, configuration is natively split across `routes.oas.json`
and `policies.json` files in a Git repository. Environment-specific values use
[environment variables](https://zuplo.com/docs/articles/environment-variables)
referenced as `$env(VARIABLE_NAME)` in configuration.

### Does Zuplo have a developer portal?

Yes. Zuplo includes a
[developer portal](https://zuplo.com/docs/dev-portal/introduction) on every
plan, auto-generated from your OpenAPI specification. It provides interactive
API documentation, an API explorer, and self-serve API key management. KrakenD
does not include a developer portal.

## Next Steps

**Ready to migrate?**
[Sign up for a free Zuplo account](https://portal.zuplo.com) and follow the
[Getting Started Guide](https://zuplo.com/docs/articles/step-1-setup-basic-gateway)
to set up your first gateway in minutes.

For planning your migration:

- [KrakenD vs Zuplo: API Gateway Comparison](/api-gateways/krakend-alternative-zuplo)
  — See a detailed feature-by-feature comparison.
- [Migrating from Self-Hosted to Managed API Gateway](/learning-center/migrate-self-hosted-to-managed-api-gateway)
  — General strategies and zero-downtime patterns for moving off self-hosted
  gateways.
- [Migrating from Kong to Zuplo](/learning-center/migrate-from-kong-to-zuplo) —
  Another migration guide for teams moving from a self-hosted gateway.
- [Migrating from Traefik to Zuplo](/learning-center/migrating-from-traefik-to-zuplo)
  — Migration guide for teams using another popular self-hosted gateway.
- [Policy Catalog](https://zuplo.com/docs/policies/overview) — Browse all
  available built-in policies.
- [Custom Policies Documentation](https://zuplo.com/docs/policies/custom-code-inbound)
  — Learn how to write your own TypeScript policies.