Kong runs several nginx workers. Module-level variables in a plugin exist once per worker, so anything shared must live in an ngx.shared dictionary or an external store.
# kong.conf
nginx_worker_processes = auto # one per CPU core
-- per worker, not per node
local counter = 0
-- per node, shared across workers
local shm = ngx.shared.kong
local n = shm:incr("hits", 1, 0)
-- per request, and correctly isolated
kong.ctx.plugin.started_at = ngx.now()
# 8 workers, module-level counter:
# 1, 1, 1, 2, 1, 2, ... requests land on different workers
#
# ngx.shared.kong:incr:
# 1, 2, 3, 4, 5, ... the node total
#
# This is also why the rate-limiting plugin's local policy is per node, and
# why cache invalidation between nodes needs the cluster events mechanism.
Run this yourself in the Online Java Compiler, spin up a live REST API in the API Sandbox, or practise with Java interview questions.
Published 2026-08-25