Mark Ku's Blog

Why try APISIX?

While using Kong's free version, I ran into limitations like Service & Route having to be bound to Service, no Consumer Group support, and limited functionality. Later I learned about APISIX, an open-source alternative, and decided to test it. After hands-on testing, APISIX performed quite well — it's an Apache Foundation project with an active community, very flexible features supporting Route Only mode, Consumer Group, hot updates, multi-language plugins, and more. A solid API Gateway worth considering.

Setting up Docker-compose and config files

During setup, since the official docs aren't detailed enough and there are some version compatibility issues, it took some time to get the environment running. Related config files are organized and on GitHub for reference:

GitHub repo

APISIX vs Kong head-to-head

Let's see what really differs:

ItemAPISIXKong (OSS)
Open-source licenseApache 2.0Apache 2.0
Core techNGINX + LuaJIT (OpenResty under the hood)NGINX + LuaJIT (OpenResty under the hood)
Config storageetcdPostgreSQL / DB-less mode
Configuration methodsREST API / etcd / YAML / DashboardREST API / YAML / Kong Manager (paid)
Plugin systemHot reload, supports Lua/Go/JavaLua plugins, also supports hot reload
PerformanceExcellent, dynamic routing performs wellStable but more conservative
Hot reload✅ Plugins load without restart✅ Also supports hot reload, but less flexible (kong reload). APISIX edges ahead on automation
Admin UI✅ Open-source version provides a decent Dashboard🔶 Third-party Konga available
K8s support✅ Native Ingress Controller✅ Kong Ingress Controller
Multi-language plugins✅ Lua / Go / Java / Wasm all work❌ Lua only
Consumer Group✅ Built-in, easy to use❌ Not supported in free version
Plugin count60+, growing50+
Rate limitingVery flexible, supports distributed architectureBasic features complete, also supports Redis distributed
Security plugins✅ JWT, key-auth, IP restrictions, WAF — comprehensive✅ JWT, ACL, etc.
API doc auto-generation✅ Built-in❌ Need to implement yourself
gRPC / WebSocket✅ Native, no extra config🔶 Need to install plugin
CommunityVery active, frequent updates from China regionStable, large global user base
Commercial backingAPI7.aiKong Inc
Maintenance complexitySlightly higher (need to manage etcd)Simpler (uses PostgreSQL)

Kong limitations discovered during testing

  1. Free version doesn't have Route only mode.
  2. Free version doesn't have Consumer Group.
  3. Free version's rate limiting is very basic.
  4. By default doesn't support dynamic routing — even when enabled, no path capture by default (need to write your own plugin).

Kong vs APISIX route configuration comparison

The scenario

Suppose you want to forward /wms/api/item/1 to http://172.62.1.1:1080/api/item/1. Here's how each does it:

Kong's setup (very tedious)

  1. First create a Service:
POST http://localhost:8001/services
Content-Type: application/json

{
  "name": "wms",
  "url": "http://localhost:1081/"
}
  1. Then create a Route:
POST http://localhost:8001/routes
Content-Type: application/json

{
  "name": "wms-api-item-1",
  "paths": ["~/wms/(?<path>api/item/1)$"],
  "strip_path": true,
  "path_handling": "v1",
  "service": {
    "name": "wms"
  },
  "tags": ["wms"]
}
  1. Finally, add a plugin to rewrite the path:
POST http://localhost:8001/plugins
Content-Type: application/json

{
  "name": "request-transformer",
  "service": {
    "name": "wms"
  },
  "tags": ["wms"],
  "config": {
    "replace": {
      "uri": "/api/item/1"
    }
  }
}

Kong needs 3 API calls, and rewriting paths requires installing an additional plugin — the configuration flow is quite complex.

APISIX's setup (simplified flow)

APISIX supports Route Only mode — one API Call gets it done:

PUT http://127.0.0.1:9180/apisix/admin/routes/api-0001
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "uri": "/wms/api/item/1",
  "name": "/wms/api/item/1",
  "priority": 10,
  "methods": ["GET", "POST", "PUT", "DELETE"],
  "plugins": {
    "proxy-rewrite": {
      "regex_uri": ["^/wms/(.*)", "/$1"]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "172.62.1.1:1080": 1
    }
  }
}

APISIX needs only 1 API Call. Built-in proxy-rewrite handles path rewriting directly — concise configuration flow.

Configuration complexity comparison

ItemKongAPISIX
Need to create Service first?✅ Required❌ No, build Route directly
Need to create Route
API Call count3 (more cumbersome)1 (relatively simple)
Configuration complexityMore complexRelatively simple

Dynamic routing conditions (flexible traffic-shaping mechanism)

One of APISIX's strengths is supporting various conditions for routing decisions — not just URI but also HTTP Method, Header, Query parameters, Host, etc. — for dynamic conditional traffic shaping.

Common dynamic conditions

  • HTTP Method: specify GET, POST, PUT, DELETE, etc.
  • Header: route based on custom Header content
  • Query parameters: decide based on URL parameters
  • Host: route based on request Host
  • Remote Addr: route based on source IP

Example: routing by Header

PUT http://127.0.0.1:9180/apisix/admin/routes/dynamic-header
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "uri": "/api/v1/resource",
  "methods": ["GET"],
  "name": "dynamic-header-route",
  "priority": 20,
  "vars": [
    ["http_x-user-type", "==", "admin"]
  ],
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "10.0.0.1:8080": 1
    }
  }
}

With this config, only requests carrying the X-User-Type: admin header get routed to the specified upstream.

Example: routing by Query parameter

PUT http://127.0.0.1:9180/apisix/admin/routes/dynamic-query
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "uri": "/api/v1/resource",
  "methods": ["GET"],
  "name": "dynamic-query-route",
  "priority": 10,
  "vars": [
    ["arg_version", "==", "beta"]
  ],
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "10.0.0.2:8080": 1
    }
  }
}

This config routes requests with ?version=beta to a different upstream.

P.S. APISIX's routing condition design is quite flexible — dynamic traffic shaping based on various request attributes.

APISIX core features

After hands-on use, here are the most useful features:

  • Route Only mode: no need to create Service first — configure Route directly. Simplified flow, fewer steps.
  • Consumer Group: no UI but operable via API; group management is flexible (though one Consumer can only belong to one Consumer Group).
  • Dynamic routing: dynamic shaping based on Header, Query parameters, IP — flexible traffic direction.
  • Rate-limit dynamic template Key: supports multi-variable rate limiting (IP+Consumer+Header) — a feature that requires Kong paid version, but APISIX provides in open source.
  • Hot-reload plugins: load new plugins or modify config without restart — easier ops, ensures service continuity.
  • Multi-language plugins: supports Lua, Go, Java, Wasm.
  • Flexible configuration: supports RESTful API, etcd, YAML.

Route Only test

Using the same /wms/api/item/1 redirect example:

PUT http://127.0.0.1:9180/apisix/admin/routes/api-0001
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "uri": "/wms/api/item/1",
  "name": "/wms/api/item/1",
  "priority": 10,
  "methods": ["GET", "POST", "PUT", "DELETE"],
  "plugins": {
    "proxy-rewrite": {
      "regex_uri": ["^/wms/(.*)", "/$1"]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": {
      "172.62.1.1:1080": 1
    }
  }
}

Consumer Group and rate-limit configuration

APISIX's Consumer Group feature is genuinely useful. Despite no UI, API operations are convenient — combined with Plugin Config you can implement group-based rate limiting:

PUT http://localhost:9180/apisix/admin/consumer_groups/free
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "plugins": {}
}

Create a rate-limit Plugin Config:

PUT http://localhost:9180/apisix/admin/plugin_configs/free_ratelimit
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "plugins": {
    "key-auth": {},
    "limit-count": {
      "count": 100,
      "time_window": 1,
      "rejected_code": 429,
      "key": "consumer_name",
      "policy": "local",
      "group": "daily"
    }
  }
}

Create a Consumer and apply the group:

PUT http://localhost:9180/apisix/admin/consumers/mark
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "username": "mark",
  "plugins": {
    "key-auth": {
      "key": "mark-api-key"
    }
  },
  "consumer_group": "standard"
}

Note! A consumer can only join one consumer group.

Rate limiting

APISIX excels in rate limiting, supporting "dynamic template key" functionality similar to what Kong only offers in its paid version. You can combine multiple variables in the key field (IP, consumer, header, etc.) for fine-grained group rate limiting.

For example:

PUT /apisix/admin/plugin_configs/pc_free
{
  "plugins": {
    "limit-count": {
      "time_window": 60,
      "count": 100,      
      "rejected_code": 429,            
      "key_type": "var_combination",      
      "key": "standard-1-47|$consumer_name", 
      "policy": "redis",      
      "redis_host": "192.168.0.15",
      "redis_port": 6379,
      "redis_timeout": 1000000,
      "redis_database": 0
    }
  }
}

P.S. This had issues in testing — there's likely a bug.

This config dynamically counts per-group based on source IP, consumer name, and the X-User-Group header — limiting data is stored in Redis. This kind of flexible group-based rate limiting requires Kong's enterprise version, but APISIX provides it in open source.


Plugin Config and plugin binding levels

APISIX supports multiple levels of plugin binding for flexible management:

LevelBinding endpointDescription
Global Rule/apisix/admin/global_rulesGlobal rules, highest priority
Consumer/apisix/admin/consumers/{username}Per-user
Consumer Group/apisix/admin/consumer_groups/{groupname}Group-managed Consumers
Route/apisix/admin/routes/{id}Per-API-route
Service/apisix/admin/services/{id}Multiple Routes can share

Plugin Configs can be reused — Routes/Services directly reference plugin_config_id, dramatically improving operational efficiency!


API grouping and querying

APISIX supports labels — add group tags to Routes, Consumers, Services for easier query and management:

{
  "uri": "/wms/api/item/1",
  "labels": {
    "group": "wms"
  },
  "name": "get-wms-item-1"
}

To query routes with group "wms":

GET /apisix/admin/routes?label=group==wms

Global plugins and monitoring config

Use Global Rule to apply global plugins like request-id, prometheus, udp-logger:

PUT http://127.0.0.1:9180/apisix/admin/global_rules/1
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "plugins": {
    "key-auth": {"_meta": {"disable": false}},
    "request-id": {"_meta": {"disable": false}},
    "prometheus": {"_meta": {"disable": false}},
    "udp-logger": {
      "host": "192.168.0.1",
      "port": 5000,
      "custom_fields": {"client_ip": "$remote_addr"}
    }
  }
}

Note: APISIX supports multiple Global Rules (for special use cases), but the Dashboard only manages one. Generally, keeping one global_rule (e.g., /global_rules/1) suffices — putting all plugin configs in a single record.

Enable Prometheus monitoring:

PUT http://localhost:9180/apisix/admin/plugins/prometheus
X-API-KEY: <your-api-key>
Content-Type: application/json

{
  "enabled": true
}

APISIX limitations (worth knowing)

While APISIX is powerful, there are some limits to be aware of. Whether using KONG or APISIX, both have constraints — for more complex traffic groupings, you may need to write your own plugin or do significant customization:

  • One consumer can only join one consumer group
  • One route can only apply one plugin config
  • Route URIs can't be duplicated
  • One Route can apply only one plugin per type
  • plugin_config doesn't support group or dynamic-condition switching, but you can use dynamic routing conditions
  • One rate-limit setting can only constrain a single time window
  • Some plugins have bugs in certain versions

Reflections

After using APISIX for a while, this open-source solution is genuinely solid. Its high flexibility, hot reload, and multi-language plugins make it a quality choice for modern API Gateway. Although some features require API operations and ops complexity is slightly higher, for scenarios needing high flexibility, group-based rate limiting, and dynamic routing, APISIX provides comprehensive solutions. Once you understand these limitations, you can more clearly decide what kind of solution to provide. But for niche API Gateway needs that are too complex, even with paid versions, unless requirements can be adjusted, custom development may still be necessary in the end.

Author

Mark Ku

擁有 10+ 年經驗的資深軟體工程師,現為 AI 應用 Builder,專注於大型平台架構與簡化複雜系統設計,從電商系統到訂閱與收費平台,結合 AI Agent、AI 整合與自動化開發,打造高效率且可持續演進的產品技術基礎。Read More

Found this useful?

The author's free tools, daily podcasts and newsletter are all here.

Mark Ku · This article is licensed under CC BY 4.0. Credit the author and link back to the original when reusing it.

Comments

Subscribe to Newsletter

Subscribe to get new posts delivered instantly — never miss a tech share.

By submitting, you agree to receive emails. You can anytime.

Popular Posts

View all
Mark Ku
··602

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution
Mark Ku
··490

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.
Mark Ku
··333

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki

A Free, Open-Source, Notion-like Knowledge Base — A Complete Guide to Deploying and Backing Up Outline Wiki
Mark Ku
··264

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning
Mark Ku
··221

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1
Mark Ku
··215

Setting Up Samba on Ubuntu to Share Folders with Windows 11

Setting Up Samba on Ubuntu to Share Folders with Windows 11
更彈性且開源的 API Gateway APISIX:實測與 Kong API Gateway 比較 - Mark Ku's Tech Notes