When One API Means Different Mocks for Each Team - Designing a Distributed WireMock Setup

Published: (February 17, 2026 at 10:21 AM EST)
7 min read
Source: Dev.to

Source: Dev.to

Where Single‑Instance WireMock Hits Its Limits

Running a single WireMock instance is straightforward:

  • POST JSON to /__admin/mappings to register stubs.
  • Reset when testing is done.

Simple. But things change when you encounter scenarios like these.

1. Scaling out for load testing

When you place multiple WireMock instances behind a load balancer, you need to distribute the same stubs to all of them. You might think, “Why not share stub JSON files via Docker volumes?” That solves file distribution, but WireMock doesn’t automatically detect file changes. To pick up changes you must either:

  • Restart each instance, or
  • Call the Admin API to reload.

With N instances that’s N operations, which quickly leads to a custom script to automate the process.

2. Multiple teams sharing the same API mock but expecting different behavior

Consider a payment‑API mock:

  • Team A wants to test primarily with success responses.
  • Team B needs to focus on timeouts and error cases.

When sharing a single WireMock instance, stub overwrites become a constant battle.

3. The learning curve for creating and editing stub definitions

WireMock stubs are written in JSON, and getting URL‑pattern matching and response structures right requires reading the documentation. Not everyone on the team can write these JSON definitions fluently, so stub creation and maintenance tend to fall on a few specific members.

Existing Options and Their Limitations

I evaluated the existing options for this problem.

OptionProsCons
WireMock Cloud (commercial SaaS)Distributed management, GUICannot self‑host, cost concerns, security‑policy constraints
Custom scripts that call the Admin APIWorks for simple syncAdds cognitive load; still a manual step. One‑click GUI sync is preferable
Git‑managed JSON files + CI/CD pipelinesElegant on paperToo heavyweight for “tweak‑a‑stub‑and‑test‑it‑immediately” cycles (commit → push → CI → deploy)

From these considerations I concluded we needed a self‑hosted tool with a GUI that provides instant deployment and centralized management of distributed instances. Thus, WireMock Hub was born.

Design Decision 1 – Why “Project” Is the Top‑Level Concept

The most important design decision in WireMock Hub was placing the project at the top of the data model.

Projects diagram

Project
├── Instance (WireMock instance): 1..N
└── Stub Mapping: 0..N

In most mock‑management tools the instance is the top‑level concept – “this instance contains these stubs.”

In our environment, multiple teams needed different mock behaviors for the same API:

  • Team A needed a payment‑API mock returning success responses.
  • Team B needed one that simulated timeouts and server errors.

By making project the top‑level concept we gain:

  1. Parallel management of multiple behaviors for the same API – create separate projects such as “Payment API – Success Testing” and “Payment API – Error Testing,” each linked to its own set of instances.
  2. Environment switching becomes project switching – dev / staging / load‑test can be expressed as distinct projects; just change the instance URLs linked to each project to deploy the same stub set to different environments.
  3. Cross‑team interference is structurally eliminated – because projects are isolated, one team’s stub changes never affect another team’s environment.

Design Decision 2 – Why Full Reset + Redeploy

WireMock Hub’s sync process uses a full reset followed by a complete redeploy approach.

Instances diagram

Sync flow:
1. DELETE /__admin/mappings on all instances (reset)
2. POST all stubs from SQLite to /__admin/mappings on all instances

You might wonder, “Wouldn’t differential sync be more efficient?” I considered it, but chose the full‑reset approach for two key reasons.

1. WireMock’s Admin API doesn’t guarantee a reliable view of the current stub state

If someone manually adds stubs via the API or another tool modifies the instance, the state Hub knows about and the actual instance state will diverge. Differential sync breaks down when this assumption fails.

2. An unknown state is the most dangerous state

In load testing we assume that mock responses are exactly what we defined. Any stray or leftover stub can cause flaky results, hidden bugs, or misleading performance metrics. By resetting first, we guarantee a clean slate before applying the authoritative stub set.

TL;DR

  • Problem: Single‑instance WireMock doesn’t scale for multi‑team, multi‑environment load‑testing scenarios.
  • Solution: WireMock Hub – a self‑hosted GUI that treats projects as the primary entity and synchronizes all instances via a full reset + redeploy cycle.
  • Result: Teams can work in parallel, switch environments with a click, and trust that the mock state is always exactly what they defined.

Feel free to reach out if you’d like to try WireMock Hub in your organization or discuss the design further!

Design Decision 2 – Full Reset Before Sync

Running with “the state is probably correct” under differential sync undermines the reliability of test results.

The cost of a full reset is acceptable.

With a few hundred stubs, a full delete and re‑register takes only seconds. Since stub deployment isn’t a frequent operation, this brief wait is not an issue.

This is a trade‑off between correctness and efficiency, and in a mock environment correctness should take priority.

Design Decision 3 – Why No External Database

The choice of SQLite as the data store was driven by the principle of minimizing the barrier to adoption.

WireMock itself is a tool that sells on “start with a single docker run.” If its management tool required setting up PostgreSQL or MySQL, the adoption barrier would become too high.

With SQLite, no external database setup is needed. Data is persisted simply by mounting a Docker volume, backups are just file copies, and sharing data between teams is as easy as sharing the SQLite file.

# This is all you need for persistence
services:
  wiremock-hub:
    image: ghcr.io/ykagano/wiremock-hub:latest
    ports:
      - "80:80"
    volumes:
      - wiremock-hub-data:/data

Note: At large scale (thousands of stubs, dozens of teams using it simultaneously), SQLite’s concurrent‑write performance could become a bottleneck. For a WireMock management tool, write frequency isn’t that high, making SQLite sufficient for now.

WireMock Hub Overview

Here’s the architecture of WireMock Hub, reflecting the design decisions above.

┌────────────────────────────────────────────────────────────┐
│                        WireMock Hub                        │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐  │
│  │   Frontend   │ -> │   Backend    │ -> │    SQLite    │  │
│  │   (Vue 3)    │    │  (Fastify)   │    │ (Persistence)│  │
│  └──────────────┘    └──────────────┘    └──────────────┘  │
└────────────────────────────────────────────────────────────┘

                              │ Sync (Full Reset + Redeploy)

         ┌────────────────────┼────────────────────┐
         │                    │                    │
         ▼                    ▼                    ▼
   ┌──────────┐         ┌──────────┐         ┌──────────┐
   │ WireMock │         │ WireMock │         │ WireMock │
   │ Instance │         │ Instance │         │ Instance │
   │    #1   │         │    #2   │         │    #3   │
   └──────────┘         └──────────┘         └──────────┘

Key Features

  • One‑click sync – Deploy stubs to all instances linked to a project with a single click. A full reset precedes deployment, ensuring no state inconsistencies.
  • Test requests – Send requests directly from the GUI to verify stub behavior. The entire cycle of creating a stub → syncing → verifying can be completed in the browser.
  • Stub generation from request logs – Convert actual requests sent to WireMock into stubs with one click, dramatically reducing the effort of writing JSON by hand.

Quick Start

The Fastest Way to Try It (All‑in‑One Image)

An image bundling both WireMock Hub and WireMock is available.

docker run -d -p 8080:80 ghcr.io/ykagano/wiremock-hub:latest
open http://localhost:8080/hub/

After starting, create a project and register http://localhost:8080 as a WireMock instance to start exploring all the features.

One Tool for Both Daily Development and Load Testing

Making projects the top‑level concept enables different use cases to coexist within a single tool.

  • Daily development – Keep the all‑in‑one image running as a single instance and use it as a mock server for your development project’s stubs. Create, test, and verify stubs entirely from the browser, replacing Postman or curl.
  • Load testing – Spin up multiple WireMock instances only when running load tests, sync the load‑testing project’s stubs to all instances at once, and shut them down when done.

The ability to handle these two fundamentally different use cases—everyday mocking and load‑test mocking—simply by switching projects is a direct benefit of placing projects at the top of the design.


GitHub:
Documentation:

Feedback and issues are very welcome!

0 views
Back to Blog

Related posts

Read more »

A Full-Stack Productivity Platform

I created Focus Portal to help people stay focused and organized in a world full of distractions. I wanted a simple platform where users could manage tasks, wri...