Where a gateway spends its time

Kong Course · lesson 15 of 15 · 6 min read

Every plugin is on the critical path of every matching request.

Open this lesson in the learning hub

Key points

  • Kong runs plugins in-process per request, in priority order. A plugin that makes a network call - to a rate-limit store, an auth server, a logging endpoint - adds its full latency to every request it matches.
  • That is the single most important gateway rule: a plugin doing synchronous I/O in the request path turns the gateway into a serial dependency on whatever it calls.
  • Rate limiting is the usual culprit. The local policy counts per node and is fast but multiplies by node count; redis is globally accurate and adds a round trip to every request.
  • Prefer asynchronous logging. A synchronous HTTP log plugin means the gateway is only as available as the log collector, which is rarely a trade anyone chose deliberately.
  • Route matching cost grows with route count and specificity. Thousands of routes with regex paths is measurably slower than the same traffic on prefix matches.
  • Watch kong_latency separately from upstream latency. The gateway reports both, and confusing them sends people optimising a backend that was never slow.

Example

# Kong reports its OWN latency separately. Read both.
#
#   X-Kong-Proxy-Latency: 3      <- time inside Kong (plugins + routing)
#   X-Kong-Upstream-Latency: 42  <- time waiting for your service
#
# Proxy latency climbing while upstream is flat = a plugin, not a backend.

# Rate limiting: pick the policy deliberately.
plugins:
  - name: rate-limiting
    config:
      minute: 100
      policy: local        # fast, per-node -> 100 x node_count effective
      # policy: redis      # globally accurate, adds a round trip per request
      # policy: cluster    # accurate-ish, and hard on the database

#   With 6 nodes and policy: local, a "100/minute" limit admits 600/minute.
#   That is usually fine for abuse protection and wrong for billing.

---
# Plugin ORDER matters - cheap and rejecting plugins first.
#
#   priority 2000  ip-restriction     reject early, costs nothing
#   priority 1250  jwt / key-auth     verify before doing any work
#   priority 1000  acl
#   priority  901  rate-limiting      after auth, so anonymous floods
#                                     are already gone
#   priority   12  http-log           LAST, and asynchronous
#
# Rate limiting BEFORE auth means you spend Redis calls on traffic you
# were going to reject anyway.

---
# Route matching: prefix beats regex, at scale.
#
#   paths: ["/api/orders"]              prefix - fast
#   paths: ["~/api/orders/[0-9]+$"]     regex  - evaluated per request
#
# Kong sorts routes by specificity, so thousands of regex routes is a
# real cost. Measure with:
$ curl -s localhost:8001/status | jq .server
$ curl -s localhost:8001/metrics | grep kong_latency

Every plugin runs on every matching request - put cheap rejecting plugins first and keep synchronous I/O out of the request path.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Kong Course course, and every lesson in it is listed on the Kong Course contents page.