What custom APISIX plugin development involves
A custom APISIX plugin is code that runs inside the gateway's request lifecycle to apply logic the built-in plugins do not provide. APISIX documents more than 100 built-in plugins covering authentication, security, traffic control, observability and AI gateway functions, so the first step is confirming that a real gap exists. Check the plugin list against the requirement, then check whether a combination of existing plugins, such as openid-connect with a route-level policy or a rate limiting rule, meets it. Only a remaining gap justifies a custom plugin.
Typical reasons to build one include a proprietary token format that must be validated at the gateway, a header policy specific to your organization, or a call to an internal policy or entitlement service before a request is forwarded. Each of these touches the request path, so it carries the same risk as any gateway change. Write down the exact input, the decision the plugin makes, the failure behavior when the internal service is slow or unavailable, and which routes it applies to.
Language is the next decision. The APISIX repository lists Lua as the native option, with plugin runners for Java, Go and Python and support for WebAssembly. Lua plugins run inside the NGINX worker and have the lowest overhead, but they require Lua and APISIX internals knowledge. Runners let teams write in a language they already maintain, at the cost of an extra process to deploy, monitor and upgrade. Confirm the current runner and WebAssembly support, and any version constraints, against the APISIX documentation for your target release before you commit.
Short answer: a small, well-scoped plugin can be built by a team already fluent in Lua or the chosen runner language. Teams without gateway internals experience, or teams building several plugins that touch authentication or traffic, often bring in a partner for design review and test harnesses. The second group benefits most from an early review of failure handling and upgrade compatibility.
What the work includes
Each plugin engagement ends with a set of artifacts the client owns and can run without the partner. The list below describes what each one contains and what to check before accepting it.
Requirements and plugin design document
This document fixes the plugin's phase in the request lifecycle, its priority relative to other plugins, its configuration schema and its failure behavior, such as whether a dependency outage rejects or passes traffic. It also records the implementation language or runner. The design sets that choice, based on your team's skills, performance needs and operating constraints, not on the partner's preference. Confirm that failure behavior is written down for each route.
Plugin source in the chosen runtime
The APISIX repository lists Lua as the native plugin language, with plugin runners for Java, Go and Python, and WebAssembly as further options. Source is delivered into your own repository and infrastructure, with build steps and dependencies documented. Ask which runtime the design selected and which runner or module version it depends on, because each option carries different operational requirements.
Automated unit and gateway tests
Unit tests cover the plugin's logic in isolation, including schema validation and error paths. Gateway-level tests run requests through a real APISIX instance to confirm phase ordering, header and body handling, and the agreed failure behavior under upstream errors. Ask for the test commands, the environment they need and a pass record that your pipeline can rerun on every change.
Packaging and deployment artifacts
Packaging turns the plugin into something your delivery pipeline can deploy, such as a versioned archive, container image or runner binary, along with the configuration needed to load it into your gateway nodes. Confirm how the artifact is versioned, how it is promoted between environments and how a rollback is performed without restarting unrelated routes.
Compatibility note for your release line
The compatibility note states which APISIX release line the plugin was built and tested against, along with any runner or dependency versions. Because plugin APIs can change between releases, this note is the basis for planning upgrades. Ask the partner to name the release line in writing and to list the upgrade checks that must run before you move to a newer one.
Operator documentation
Operator documentation covers how to configure the plugin on routes, the meaning of each schema field, expected log and metric output, known limits and the runbook for common failures. It is written for the team that will run the gateway after handover, so ask for it to be reviewed by someone who did not write the plugin.
What drives cost and duration
The table lists the factors that move effort for a custom APISIX plugin, why each one matters and how to keep it under control, and effort depends on the written scope, so no duration or price is given here.
| Driver | Why it matters | How to keep it down |
|---|---|---|
| Implementation language or runner | Lua plugins run inside the gateway process. Java, Go, Python runners and WebAssembly add a separate execution path with its own build, test and deployment chain. | Use Lua where the team already supports it. Choose a runner only when the required library or existing code justifies a second toolchain. |
| Number and complexity of plugins | Each plugin needs its own schema, logic, tests and documentation. Plugins that combine several phases or shared state take more design work. | Bundle related behavior into fewer plugins and keep each one focused on a single, testable job. |
| Authentication or request body handling | Plugins that verify credentials or read and rewrite request bodies affect security review, performance testing and error handling for every route they touch. | Limit body access to routes that need it and reuse built-in authentication plugins where they meet the requirement. |
| External service integration | Calls to identity providers, policy engines or logging backends add timeouts, retries, failure modes and credentials to manage and test. | Agree the service contract, timeouts and fallback behavior in writing before build starts, and use test doubles for most of the suite. |
| Depth of test coverage | Unit, integration and gateway-level tests against a running APISIX instance each add setup and maintenance. Required coverage depth is set by the client. | Define the test levels and pass criteria in the scope, and reuse one test harness across plugins. |
| APISIX environments and release lines | Each environment and each supported APISIX release line may need a separate build, validation and compatibility check before rollout. | Reduce the number of supported release lines, and confirm the upgrade policy with the client before build starts. |
| Change control and security review | Formal approval gates, code review requirements and security testing add review cycles and evidence to produce for each release. | Agree the review path, reviewers and evidence format up front, and keep changes small so each review stays bounded. |
| Edition chosen | Open source APISIX and a commercial APISIX-based distribution differ in packaging, support terms and available features, which can change what the plugin must work with. | Confirm the edition and its plugin and runner support with the vendor before scoping, since this decision sets the build baseline. |
Project phases and outputs
The sequence moves from understanding the current gateway to a tested plugin running on the fleet, with a handover that keeps upgrades predictable.
Discover current gateway state
We inventory the existing APISIX deployment, including its deployment mode (traditional, decoupled or standalone), installed plugins, routes, consumers and runtime model, and confirm the exact target APISIX version. The output is a written discovery note that lists which behaviors the plugin must respect and which open questions your team must answer before design begins.
Design the plugin and its interfaces
We define what the plugin does, which request phases it hooks into, its configuration schema, the inputs it reads from routes and consumers, and the failure behavior when a dependency is unavailable. The output is an approved design document that your security and platform owners sign off on before any code is written.
Prove the language and runner choice
We build a small spike that runs the chosen approach (Lua, a Java, Go or Python plugin runner, or WebAssembly) against your target APISIX version in a test environment. The spike closes when a sample request passes through the plugin with measured behavior, and the result either confirms the design or sends it back to revision.
Build the plugin with unit tests
We implement the plugin and its unit tests, covering configuration validation, request handling and error paths. The step closes when the test suite passes in your source control system and the code review is complete, with the repository holding the code, tests and build definition.
Run gateway-level integration tests
We deploy the plugin to a staging environment that mirrors your production deployment mode and runs the same route and authentication configuration. Integration tests cover traffic through real gateway nodes, Admin API or configuration updates, and failure scenarios. The step closes with a test report that your team accepts.
Package and roll out to the fleet
We produce a versioned artifact and roll it out to the gateway nodes in stages, with a documented rollback procedure and monitoring on error rates and latency. The step closes when every node reports the new plugin version and the rollout log is filed with your operations team.
Hand over with upgrade compatibility checks
We transfer the source, build pipeline, runbook and test suite to your team and walk through the checks to run before each APISIX upgrade, including plugin API changes between releases. The handover closes when your engineers run the test suite themselves and the compatibility checklist is accepted.
What teams keep in-house and what they outsource
This table compares who usually owns each part of an APISIX custom plugin project and which skills each side needs, so you can decide where to build internal capacity and where a partner adds the most value.
| Work area | Usually kept in-house | Usually outsourced | Skills each side needs |
|---|---|---|---|
| Business rules and policy ownership | Yes. Teams define which requests are allowed, which claims map to which routes, and who approves changes to them. | Rarely. A partner may help write down rules from interviews, but approval stays with your owners. | In-house: domain knowledge, security policy, change approval. Partner: requirements capture and translating rules into plugin behavior. |
| Plugin architecture and language choice | Often shared. Your architects set constraints such as runner language and operating model, while the partner proposes the plugin design. | Often shared. Outside experience helps compare Lua with the Java, Go, Python or WebAssembly options against your team's skills. | Gateway architecture, NGINX request lifecycle, plugin phases, and the runtime cost of each language option. |
| Implementation in Lua or the plugin runner | Shared or in-house for maintenance once the plugin is handed over and documented. | Usually outsourced during the build, since gateway internals are where outside experience tends to save rework. | Lua or the chosen runner language, APISIX plugin API and configuration schema, NGINX and APISIX internals, and error handling under load. |
| Test harness and CI pipeline | Owned in-house so the plugin is tested with the same pipeline as other gateway code. | Often outsourced to build the first harness, then transferred to your DevOps and QA staff. | DevOps for pipeline and container builds, QA for test design, and gateway knowledge for simulating upstreams and failure cases. |
| Security review of plugin code | Your security team sets the review criteria and signs off on release. | Often split. A partner can review its own code, and an independent reviewer can test it separately. | Security engineering for code review, threat modeling of request handling, secrets handling, and log content checks. |
| Upgrade testing | Owned in-house as part of platform operations, with the release line and change calendar. | Available as a retainer that retests plugins against new APISIX releases before you upgrade. | Platform operations for staging environments, rollback plans, and reading APISIX release notes against plugin code. |
What usually goes wrong
Most custom plugin problems come from decisions made early or from code that was never built to outlast its first release. The cards below name the failure patterns we see most often and the preventive step for each.
Duplicating a built-in plugin
APISIX documents more than 100 built-in plugins covering authentication, security, traffic control and observability. Before writing code, map each requirement to an existing plugin and its configuration options. A custom plugin that repeats built-in behavior adds maintenance cost and a second place for bugs to hide. Record why each gap cannot be closed by configuration.
Choosing a runner without checking support
Lua, the Java, Go and Python plugin runners, and WebAssembly each carry different constraints on performance, deployment and supported features. Confirm runner and WebAssembly support against the APISIX documentation for the exact release you run, not the latest one. Choose the path only after a proof of concept runs in a environment matching production.
Blocking calls in the request path
A plugin that makes synchronous calls to an external token service, policy engine or database can stall worker processes under load and slow every route it touches. Identify each external dependency in the request path, set explicit timeouts, and decide whether caching or asynchronous work is acceptable. Load test the plugin with the dependency slowed down, not only with it healthy.
No failure-mode decision
When the plugin's dependency is unavailable, the gateway either rejects traffic (fail closed) or passes it through (fail open). Many projects never record which applies to which route. Document the decision per route class, including security-sensitive routes, and test both outcomes. Get the decision signed off by the team that owns the protected service.
Passing tests but breaking on upgrade
Plugin code often depends on internal APIs or behavior that changes between APISIX release lines. Tests that run only against the version used during development will not catch this. Pin the target release, run the plugin test suite against each release line you plan to adopt, and include upgrade checks in your change process before any production rollout.
Schema changes that break existing routes
Changing a plugin's configuration schema, such as renaming a field or tightening a validation rule, can cause existing route definitions to fail validation or change behavior silently. Version schema changes, keep old fields accepted during a transition, and validate every stored route configuration against the new schema in staging before release.
Undocumented plugins only the author can run
A plugin that exists only in one engineer's head becomes a risk the first time that person leaves or is unavailable during an incident. Require a README covering configuration fields, failure behavior, dependencies, build and packaging steps, and a runbook for common errors. Store the source, tests and build pipeline in version control that more than one person can access.
How the work changes by starting point
Your team already runs APISIX and knows Lua, so most of the work sits in the plugin logic and how it fits your current configuration. The main design question is how the plugin interacts with the routes, consumers and etcd-backed settings you already operate.
- Design: Confirm the plugin priority and execution phase so it does not conflict with built-in plugins on the same routes.
- Testing: Run the test suite against a staging gateway on the same APISIX version as production.
- Packaging: Add the plugin files to your existing image or deployment pipeline, and document how they are loaded.
- Confirm: Check the plugin development guide for the current Lua hook names and interface for your target release.
Your services are written in Java, Go or Python, so the plugin is written in that language and reaches the gateway through an external plugin runner. This adds a process you must deploy, monitor and version alongside the gateway.
- Design: Keep plugin logic lightweight, since each request crosses a process boundary between the gateway and the runner.
- Testing: Measure the latency the runner adds under your expected request volume before approving the design.
- Packaging: Build the runner with locked dependencies and a container image that matches a supported runner version.
- Operations: Add runner health checks and restart behavior to monitoring, because a failed runner affects request handling.
- Confirm: Verify which runner and language SDK versions the vendor documentation supports for your APISIX release.
WebAssembly lets one compiled plugin move between gateway environments without rebuilding it for each one. The trade-off is a narrower set of toolchains and a runtime that you must test in your own environment.
- Design: Confirm which host functions the plugin interface exposes, since your logic can only use what the gateway provides.
- Testing: Test the compiled module against every gateway version you run, because the interface can change between releases.
- Packaging: Version each module with its source revision and toolchain version so it can be rebuilt and audited.
- Operations: Check module size and load behavior in staging before any production rollout.
- Confirm: Check the supported source languages, SDK version and Wasm runtime bundled with your APISIX release.
When APISIX runs under the APISIX Ingress Controller, plugin configuration reaches the gateway through Kubernetes resources, so changes follow your manifest and review process. The controller is a separate project, so its release line may not match the gateway release line.
- Design: Map each plugin to the Kubernetes resource kind that carries its configuration, and confirm which kinds your controller version supports.
- Testing: Apply plugin changes first in a non-production cluster running the same controller version.
- Packaging: Store manifests in Git, deploy them through your GitOps tooling, and keep secrets out of the manifests.
- Operations: Watch cluster events and controller logs for rejected resources, since configuration errors surface there first.
- Confirm: Check the controller release notes for plugin support and the version pairing with your gateway release.
In an air-gapped network, every dependency, plugin package and build tool must be mirrored in before work starts. Any build step that reaches the internet will fail or stall, so the mirror becomes your only source during the project.
- Design: Inventory every Lua package, runner package, Wasm toolchain and base image the plugin needs, including transitive dependencies.
- Testing: Run the build and test suite inside the isolated network so missing packages surface early.
- Packaging: Produce internally hosted artifacts with checksums or signatures, and record the exact versions mirrored.
- Upgrades: Refresh the mirror each time you adopt a new gateway or plugin release.
- Confirm: Ask the vendor documentation which dependencies are fetched at build time and which are needed at runtime.
What you need to provide
The quality of your inputs decides how precise the fixed-scope quote can be. Before work starts, provide a written list of the behaviors the custom plugin must perform, with a named business owner for each one. Each behavior should state the trigger (for example, a request path or header), the expected result, and the failure response. Without this list, the plugin scope can only be estimated, and the quote will carry more open assumptions.
Give the delivery team access to the current gateway configuration and confirm the exact APISIX version in use, along with the deployment mode (traditional, decoupled or standalone). Plugin code must be tested against the same version and mode as production, so a staging environment matching that deployment mode is required. Confirm the Admin API port and how configuration reaches each gateway node, because these affect how the plugin is loaded and tested.
Provide access to the source repository, the CI system and the artifact registry where plugin packages will be stored. If the plugin calls an identity provider or another external service, supply test endpoints and test credentials, and confirm whether those services have their own change windows. Name the security review contacts who will approve the code and the threat model, and write down your change-control rules, including who can approve a production rollout. Finally, name the engineer who will own the plugin after handover. That person should be present during build and testing, not only at the end.
Frequently asked questions
Do we need a custom APISIX plugin, or is a built-in plugin enough?
Often a built-in plugin, or a combination of existing plugins, covers the requirement, so check that first. The APISIX documentation describes more than 100 built-in plugins covering authentication, security, traffic control, observability and AI gateway functions. Map each requirement to a plugin, its configuration options and its documented limits. Review options such as openid-connect, key-auth, jwt-auth and forward-auth before writing code. A custom plugin is justified when the logic is specific to your organization, such as a proprietary token check or a header transformation that no configuration can express.
Which language should a custom APISIX plugin use?
The choice depends on where the logic runs, the skills your team already has and the latency and operational overhead you accept. Custom plugins can be written in Lua, or through plugin runners in Java, Go or Python, and WebAssembly is also supported. Lua plugins run inside the gateway process and suit lightweight request logic. Runners execute your code as external processes, which suits teams that already maintain services in those languages. Weigh the performance budget of the affected routes, the libraries the logic needs and who will maintain the code. Confirm runner details against the documentation for your APISIX release line.
What does custom plugin development cost, and what drives the quote?
No price is published here, and a quote follows from a written scope. Most of the cost is skilled labor: requirements analysis, design of the plugin configuration schema, implementation in the chosen language or runner, automated tests, packaging, documentation and handover. Costs rise with the number of behaviors, the external systems the plugin calls, the depth of security review and the number of gateway environments to test. Build and handover are one-time costs. Upgrade testing and maintenance recur and can be kept in-house or placed under a retainer. Ask each quote to price build, testing, handover and optional support separately.
How long does custom APISIX plugin development take?
Duration depends on the scope and the phases it contains, so ask for a phase-by-phase schedule in the written scope. The usual phases are requirements and design, build, testing against your routes and identity setup, deployment to non-production gateways, then handover. The main drivers are the number of plugin behaviors, dependencies on identity providers or backend APIs, access to test environments and the pace of your security review. You can shorten the work by providing sample requests and responses, the authentication design, the target APISIX version and named reviewers early in the engagement.
Can our team maintain the plugin, and how is upgrade compatibility kept?
Yes, provided the plugin arrives with source control, an automated test suite, build packaging and documentation your engineers can run. Handover should cover the code structure, the configuration schema and an upgrade checklist. Compatibility is kept by pinning the APISIX release line you support, running the test suite against each new release in a non-production gateway and reviewing deprecation notes before you upgrade. Plugin changes should pass the same review as route changes. Your team can run these steps in-house, or you can place upgrade testing under a support retainer.
Can a partner build inside our infrastructure, and do we own the code?
Yes, DeployOpen works inside infrastructure you control, including your cloud accounts, data centers and air-gapped networks, so source code, secrets and test data can stay in your environment. Ownership of source, documentation and deliverables should be written into the scope before work starts. Confirm that terms with your procurement and legal teams. APISIX is released under the Apache License 2.0, so review the license of every dependency your plugin uses. Agree on repository access and an access model for your team at the start.
How DeployOpen delivers this service
DeployOpen plans, builds, tests and documents Apache APISIX custom plugins inside your own infrastructure, using a written scope agreed before work starts. Engagements are fixed-scope, and ongoing support is available as a retainer.
How we scope
- We record which plugin behaviors, requests and responses the written scope covers before any code is written.
- We confirm the runner choice (Lua, Java, Go, Python or WebAssembly) against your team's skills and your APISIX release line.
- We list the upstream services, identity providers and logging targets each plugin must interact with, and who owns each.
How we build
- We develop each plugin against the APISIX version you run, with schema validation and configuration checked in version control.
- We test plugin logic in a non-production APISIX instance that mirrors your deployment mode, including failure and timeout paths.
- We package plugins and their configuration so that your team can reproduce the build and deploy it through your own pipeline.
How we hand over
- We deliver plugin source, test suites, build instructions and a record of the APISIX versions each release was validated against.
- We walk your engineers through how to load, reload and roll back a plugin in the environments you operate.
- We document known limits, such as plugin behavior under etcd or node failure, so your team can plan operations around them.
How we support
- We recommend a compatibility check for each planned APISIX upgrade, covering custom plugins and their tests before rollout.
- Ongoing support, upgrades and testing are available as a retainer, and its scope is set in writing like any other engagement.
- Retainer work can cover updates to plugins when APISIX release changes affect their interfaces or dependencies.

