Concurrency & Named Queues
When AI agents execute workflows, they often trigger parallel requests. In many real-world scenarios—such as browser automation, hardware interaction, shared database mutations, or rate-limited third-party APIs—concurrent executions lead to race conditions, locked tables, or inconsistent application states.
mcponce features a high-performance FIFO Concurrency Engine capable of handling over 1,800,000 queue operations per second with negligible overhead.
View diagram source
graph TD
subgraph Invocations
T1[click_button]
T2[type_text]
T3[read_page]
end
subgraph Named Mutex Queue: 'browser'
Q[FIFO Mutex Queue]
end
T1 --> Q
T2 --> Q
Q --> Execution[Browser Instance]
T3 -.-> DirectExecution[Direct Non-Conflicting Execution]
1. Named Mutex Queues (Cross-Tool Synchronization) #
The most common concurrency problem in MCP is synchronizing different tools that manipulate the same underlying resource.
By setting sequential: "name", tools sharing the same string key are serialized in a dedicated FIFO queue without blocking unrelated tools:
import { createMcpServer } from 'mcponce';
const app = createMcpServer({ name: 'browser-automation' });
// All tools targeting 'browser' will run one-by-one in FIFO order
app.tool({
name: 'browser_navigate',
sequential: 'browser',
handler: async ({ url }) => {
return page.goto(url);
}
});
app.tool({
name: 'browser_click',
sequential: 'browser',
handler: async ({ selector }) => {
return page.click(selector);
}
});
app.tool({
name: 'browser_type',
sequential: 'browser',
handler: async ({ selector, text }) => {
return page.fill(selector, text);
}
});
// Unrelated tools run concurrently without delay
app.tool({
name: 'calculate_checksum',
handler: async ({ data }) => crypto.createHash('sha256').update(data).digest('hex')
});
2. Tool-Level Concurrency #
You can also control concurrency per individual tool:
app.tool({
name: 'write_audit_log',
description: 'Appends to disk file sequentially',
// Ensures this specific tool never runs multiple invocations in parallel
sequential: true,
handler: async ({ message }) => {
await fs.promises.appendFile('/var/log/audit.log', message + '\n');
}
});
3. Server-Level Concurrency #
If your entire server interacts with a single exclusive resource (such as a local database file or connected USB device), you can enforce concurrency rules globally:
const app = createMcpServer({
name: 'sqlite-manager',
// Entire server executes strictly one tool at a time (FIFO)
sequential: true
});
4. Programmatic Invocation Overrides #
When calling tools programmatically via app.callTool(...) or context.callTool(...), you can override or specify queueing behavior dynamically:
// Enforce sequential execution on the 'database' queue for this specific call
await app.callTool('run_migration', { step: 1 }, {
sequential: 'database'
});
Performance Characteristics #
In high-throughput stress testing with 50,000 queued items across 20 concurrent workers:
- Throughput: ~1,850,000 operations / sec
- Allocation overhead: < 80 bytes per queued promise
- Fairness: Guaranteed FIFO order execution with zero starvation