Stackbook Logo
← Back to Tools

Kong API Gateway Guide

Run Kong as an API gateway: services, routes, plugins for auth and rate limiting, declarative DB-less config, and operational pitfalls.

4 min read

What it is and when to use it

Kong is an open-source API gateway built on NGINX and Lua. It sits in front of your upstream services and handles cross-cutting concerns: authentication, rate limiting, request transformation, logging, caching and traffic control. Clients talk to Kong, and Kong proxies to the right backend.

Use it when many services need the same policies, when you want a single public entry point, or when you need a plugin ecosystem without writing gateway code yourself. For a single backend with simple needs, a plain reverse proxy may be enough.

Quick start

DB-less mode keeps the whole configuration in one declarative file, which suits GitOps workflows.

_format_version: "3.0"

services:
  - name: orders
    url: http://orders.internal:8080
    routes:
      - name: orders-route
        paths:
          - /orders
        strip_path: true

plugins:
  - name: rate-limiting
    service: orders
    config:
      minute: 60
      policy: local
docker run -d --name kong \
  -e KONG_DATABASE=off \
  -e KONG_DECLARATIVE_CONFIG=/kong/kong.yml \
  -e KONG_PROXY_LISTEN=0.0.0.0:8000 \
  -e KONG_ADMIN_LISTEN=127.0.0.1:8001 \
  -v $(pwd)/kong.yml:/kong/kong.yml \
  -p 8000:8000 kong:3.7

curl -i localhost:8000/orders/42

Core concepts

Service represents an upstream API. Route defines how requests match it by path, host, method or headers. Upstream and targets add load balancing and health checks across several instances. Consumer represents an API client, and plugins attach behavior globally or to a service, route or consumer.

In database mode, manage everything through the Admin API:

curl -X POST localhost:8001/services \
  -d name=billing -d url=http://billing.internal:9000

curl -X POST localhost:8001/services/billing/routes \
  -d name=billing-route -d 'paths[]=/billing'

curl -X POST localhost:8001/services/billing/plugins \
  -d name=key-auth

curl -X POST localhost:8001/consumers -d username=mobile-app
curl -X POST localhost:8001/consumers/mobile-app/key-auth -d key=change-me

Clients then send the header apikey: change-me.

Useful plugins

  • Authentication: key-auth, jwt, oauth2, openid-connect (enterprise) and basic-auth.
  • Traffic control: rate-limiting, request-size-limiting, ip-restriction and cors.
  • Transformation: request-transformer and response-transformer.
  • Observability: prometheus, opentelemetry, http-log and correlation-id.

Load balancing with active health checks:

upstreams:
  - name: orders-upstream
    healthchecks:
      active:
        http_path: /health
        healthy:
          interval: 5
          successes: 2
        unhealthy:
          interval: 5
          http_failures: 3
    targets:
      - target: orders-1.internal:8080
      - target: orders-2.internal:8080

Point the service host at orders-upstream to use it. Validate a declarative file before deploying with kong config parse kong.yml.

Pitfalls

  • Exposed Admin API. It grants full control. Bind it to localhost or a private network and protect it with RBAC or a gateway route with authentication.
  • Local rate limiting across nodes. With policy: local, each node counts separately, so the effective limit multiplies. Use the redis policy for a shared counter.
  • Path matching surprises. Route matching prefers longer paths and regular expressions need the tilde prefix. With strip_path the upstream sees a different URL than the client sent.
  • Plugin ordering. Plugins run in a fixed priority order, so for example authentication runs before rate limiting by consumer.
  • Treating the gateway as business logic. Keep it to cross-cutting concerns. Heavy transformation belongs in services.
  • Database mode in production without planning. Postgres becomes a dependency, and configuration changes propagate with a short delay. Hybrid mode with a separate control plane reduces that risk.
  • Missing timeouts. Tune connect_timeout, read_timeout and retries per service to avoid retry storms on non-idempotent calls.

How it fits an architecture

Kong is the north-south edge: internet traffic arrives through a load balancer, Kong enforces authentication, quotas and routing, and forwards to services in a cluster. On Kubernetes, the Kong Ingress Controller translates Ingress and Gateway API resources into Kong configuration. Combine it with Redis for distributed counters, Prometheus and OpenTelemetry for metrics and traces, and a service mesh for east-west traffic. Run at least two or three stateless nodes behind a load balancer for availability.

Key takeaways

  • Kong centralizes authentication, rate limiting and routing in front of your services.
  • DB-less declarative config suits version-controlled, immutable deployments.
  • Model APIs as services and routes, and attach plugins at the narrowest useful scope.
  • Lock down the Admin API and use a shared policy for cluster-wide rate limits.
  • Add health checks and sensible timeouts to protect upstreams.
  • Keep business logic out of the gateway.