As organizations break monolithic applications into microservices, one challenge quickly surfaces: how do you manage dozens or even hundreds of services, each with its own endpoints, authentication requirements, and rate limits? The answer is an API gateway, and Kong API Gateway stands out as one of the most mature, performant, and extensible options available today.
In this guide, we walk through what an API gateway does, why Kong is a strong choice for api management in a microservices environment, and how to install, configure, and extend Kong with plugins that handle rate limiting, authentication, logging, and more. By the end, you will have a working declarative configuration you can adapt for your own infrastructure.
What Does an API Gateway Do?
An API gateway sits between your clients (browsers, mobile apps, third-party integrators) and your backend services. Instead of exposing each microservice directly, all traffic flows through a single entry point. The gateway then routes requests to the correct service based on the path, host, headers, or other criteria.
Beyond simple routing, a well-configured kong api gateway provides:
- Authentication and authorization -- Verify API keys, JWT tokens, or OAuth credentials before requests ever reach your services.
- Rate limiting -- Protect services from abuse and ensure fair usage across consumers.
- Request and response transformation -- Modify headers, query parameters, or payloads on the fly without changing service code.
- Load balancing -- Distribute traffic across multiple instances of the same service.
- Logging and monitoring -- Capture request metrics, latency data, and error rates in a centralized location.
- Circuit breaking -- Prevent cascading failures by stopping traffic to unhealthy services.
Without an API gateway, each microservice would need to implement these concerns independently, leading to duplicated logic, inconsistent behavior, and a significantly larger attack surface. The gateway pattern centralizes cross-cutting concerns so your services can focus on business logic.
Why Kong for API Management?
There are several API gateway solutions on the market -- NGINX-based proxies, AWS API Gateway, Traefik, and others. Kong distinguishes itself in several important ways:
Performance at scale. Kong is built on top of NGINX and OpenResty, which means it inherits their battle-tested performance characteristics. It can handle tens of thousands of requests per second with sub-millisecond latency overhead. For microservices architectures where every millisecond matters, this is critical.
Plugin ecosystem. Kong ships with over 100 plugins covering authentication, security, traffic control, analytics, transformations, and logging. If the built-in plugins do not meet your needs, you can write custom plugins in Lua, Go, Python, or JavaScript.
Declarative configuration. Kong supports a fully declarative YAML-based configuration model (DB-less mode), which integrates naturally with GitOps workflows and infrastructure-as-code practices. You can version your gateway configuration alongside your application code.
Platform flexibility. Kong runs on bare metal, VMs, Docker, Kubernetes (via the Kong Ingress Controller), and all major cloud providers. This flexibility means it fits into whatever infrastructure you already operate.
Open source foundation. Kong Gateway OSS is open source under the Apache 2.0 license. Kong Enterprise adds features like RBAC, developer portals, and advanced analytics, but the open source version is fully capable for most production workloads.
Installation and Initial Setup
Kong supports multiple deployment models. For this guide, we will use Docker Compose to run Kong in DB-less declarative mode, which is the simplest path to a production-ready configuration.
First, create a docker-compose.yml file:
version: "3.8"
services:
kong:
image: kong/kong-gateway:3.6
container_name: kong-gateway
environment:
KONG_DATABASE: "off"
KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
KONG_PROXY_LISTEN: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
KONG_ADMIN_LISTEN: "0.0.0.0:8001"
KONG_ADMIN_GUI_LISTEN: "0.0.0.0:8002"
KONG_LOG_LEVEL: info
ports:
- "8000:8000" # Proxy (HTTP)
- "8443:8443" # Proxy (HTTPS)
- "8001:8001" # Admin API
- "8002:8002" # Admin GUI
volumes:
- ./kong.yml:/etc/kong/kong.yml:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "kong", "health"]
interval: 30s
timeout: 10s
retries: 3
The key environment variable is KONG_DATABASE: "off", which tells Kong to run without a database and load its entire configuration from the YAML file mounted at /etc/kong/kong.yml. This is ideal for version-controlled, reproducible deployments.
Start Kong with:
docker compose up -d
Verify it is running:
curl -s http://localhost:8001/status | jq .
You should see a JSON response with server information and database reachability set to off.
Configuring Routes and Services
The declarative configuration file (kong.yml) defines your services, routes, consumers, and plugins. Here is a foundational example that routes traffic to three microservices:
_format_version: "3.0"
_transform: true
services:
- name: user-service
url: http://user-service:3000
routes:
- name: user-routes
paths:
- /api/users
strip_path: false
methods:
- GET
- POST
- PUT
- DELETE
- name: order-service
url: http://order-service:3001
routes:
- name: order-routes
paths:
- /api/orders
strip_path: false
methods:
- GET
- POST
- name: product-service
url: http://product-service:3002
routes:
- name: product-routes
paths:
- /api/products
strip_path: false
retries: 3
connect_timeout: 5000
read_timeout: 30000
write_timeout: 30000
Each service represents a backend microservice, defined by its upstream URL. Each route maps incoming request patterns (paths, methods, headers, hosts) to a service. When a client sends a request to http://your-gateway:8000/api/users, Kong matches it to the user-routes route and proxies it to http://user-service:3000/api/users.
The strip_path setting controls whether Kong removes the matched path prefix before forwarding. Setting it to false preserves the original path, which is usually what you want when your microservices expect those path prefixes.
For services that need more resilience, you can configure retries, connect_timeout, read_timeout, and write_timeout directly on the service definition. You can also define upstreams with multiple targets for load balancing:
upstreams:
- name: user-service-upstream
algorithm: round-robin
healthchecks:
active:
healthy:
interval: 10
successes: 3
unhealthy:
interval: 5
http_failures: 3
targets:
- target: user-service-1:3000
weight: 100
- target: user-service-2:3000
weight: 100
This upstream definition tells Kong to load balance across two instances of the user service using round-robin, with active health checks that mark a target as unhealthy after three consecutive failures.
Essential Plugins: Rate Limiting, Authentication, and Logging
Plugins are where Kong truly shines for api management. They can be applied globally, per service, per route, or per consumer. Here is how to configure three essential plugins in your declarative YAML.
Rate Limiting
Protect your services from traffic spikes and abuse:
plugins:
- name: rate-limiting
service: order-service
config:
minute: 100
hour: 5000
policy: local
fault_tolerant: true
hide_client_headers: false
This applies a rate limit of 100 requests per minute and 5,000 per hour to the order service. The policy: local option stores counters in memory on each Kong node. For multi-node deployments, use policy: redis with a shared Redis instance to ensure consistent counting across all gateway instances.
When a client exceeds the limit, Kong returns a 429 Too Many Requests response with RateLimit-Remaining and RateLimit-Reset headers so clients can implement backoff logic.
Authentication with API Keys
Require API key authentication on sensitive routes:
plugins:
- name: key-auth
service: order-service
config:
key_names:
- X-API-Key
- apikey
hide_credentials: true
consumers:
- username: mobile-app
keyauth_credentials:
- key: mk_live_a1b2c3d4e5f6g7h8i9j0
- username: partner-integration
keyauth_credentials:
- key: mk_live_z9y8x7w6v5u4t3s2r1q0
With this configuration, any request to the order service must include a valid API key in the X-API-Key header or apikey query parameter. The hide_credentials: true setting strips the key from the request before forwarding it to the upstream service, preventing accidental credential leakage.
For more advanced authentication, Kong supports JWT validation, OAuth 2.0, LDAP, mutual TLS, and OpenID Connect (Enterprise). You can also layer multiple auth plugins on the same route for defense in depth.
Logging with HTTP Log Plugin
Send request and response metadata to an external logging service:
plugins:
- name: http-log
config:
http_endpoint: http://logging-service:9200/_bulk
method: POST
timeout: 10000
keepalive: 60000
flush_timeout: 2
retry_count: 3
content_type: application/json
- name: correlation-id
config:
header_name: X-Request-ID
generator: uuid
echo_downstream: true
The http-log plugin sends structured JSON logs for every proxied request. Combined with the correlation-id plugin, every request gets a unique ID that propagates through your entire microservices call chain, making distributed tracing straightforward.
Kong also supports logging plugins for Syslog, TCP/UDP, file logging, StatsD, Datadog, and Prometheus. Choose the plugin that matches your observability stack.
Monitoring and Observability
Production API gateways need comprehensive monitoring. Kong integrates with Prometheus out of the box through a dedicated plugin:
plugins:
- name: prometheus
config:
per_consumer: true
status_code_metrics: true
latency_metrics: true
bandwidth_metrics: true
upstream_health_metrics: true
This exposes a /metrics endpoint on Kong's admin API (port 8001) in Prometheus format. You can scrape this endpoint with Prometheus and visualize the data in Grafana. Key metrics to monitor include:
- kong_http_requests_total -- Total request count by service, route, and status code.
- kong_request_latency_ms -- End-to-end request latency (client to Kong to upstream and back).
- kong_upstream_latency_ms -- Time spent waiting for the upstream service, isolating gateway overhead from service performance.
- kong_bandwidth_bytes -- Ingress and egress bandwidth by service.
- kong_upstream_target_health -- Health status of upstream targets, critical for detecting service degradation.
Set up alerts on error rate spikes (5xx responses exceeding a threshold), latency percentile degradation (p99 exceeding your SLA), and upstream health changes. These three categories of alerts will catch the vast majority of production issues before they impact end users.
For a complete observability setup, consider pairing Kong's Prometheus plugin with distributed tracing via OpenTelemetry. Kong 3.x includes built-in OpenTelemetry support, allowing you to trace requests from the gateway through every microservice in your architecture.
Production Considerations
Before deploying Kong to production, address these additional concerns:
TLS termination. Configure Kong to terminate TLS at the gateway so internal service-to-service communication can remain plaintext (within a trusted network). Mount your certificates in the Kong container and reference them in the declarative config.
Configuration validation. Always validate your declarative config before deploying:
kong config parse /etc/kong/kong.yml
This catches syntax errors and invalid references before they cause gateway downtime.
Blue-green deployments. Because Kong's declarative config is a single file, you can implement blue-green deployments by loading a new configuration and verifying it against a canary traffic slice before full rollout.
Security hardening. Restrict access to the Admin API (port 8001) to internal networks only. In Kubernetes, use network policies to prevent external access. Never expose the Admin API to the public internet.
Consumer management at scale. For large numbers of API consumers, consider using Kong's consumer groups feature to apply rate limits and plugins to cohorts of consumers rather than individually.
Moving Forward with API Gateway Architecture
Implementing a kong api gateway is one of the most impactful infrastructure decisions you can make when adopting microservices. It centralizes cross-cutting concerns, simplifies client integration, improves security, and gives you a single pane of glass for monitoring all API traffic.
The declarative configuration approach shown in this guide means your gateway setup lives in version control, can be reviewed in pull requests, and deploys reproducibly across environments. As your microservices architecture grows, Kong scales with you -- add new services and routes to the YAML, apply plugins for the policies you need, and let the gateway handle the rest.
If your team is building or migrating to a microservices architecture and needs help designing your API gateway layer, our engineers at Maranatha Technologies have extensive experience with Kong and modern infrastructure patterns. Visit our custom software development services to learn how we can help you build scalable, well-architected systems.