This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-sqlite-wal-threading-boundary

Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines

Enforces a strict single-writer, dedicated-reader thread boundary for SQLite Write-Ahead Logging (WAL) in Kotlin Multiplatform targets. Prevents priority inversion, thread pool starvation, and hard database lock deadlocks between Apple Grand Central Dispatch (GCD) workloops and Kotlin Coroutine dispatchers by isolating SQLite connections to specialized, confined dispatchers.

Prohibited Anti-Pattern: Dispatching SQLite WAL Mutations Across Unconfined Coroutine Pools and Native Apple GCD Queues

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines - Enforces a strict single-writer, dedicated-reader thread boundary for SQLite Write-Ahead Logging (WAL) in Kotlin Multiplatform targets. Prevents priority inversion, thread pool starvation, and hard database lock deadlocks between Apple Grand Central Dispatch (GCD) workloops and Kotlin Coroutine dispatchers by isolating SQLite connections to specialized, confined dispatchers.
globs: **/commonMain/**/*.kt, **/iosMain/**/*.kt, **/appleMain/**/*.kt, **/database/**/*.kt, **/db/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-sqlite-wal-threading-boundary"
---

# Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Dispatching SQLite WAL Mutations Across Unconfined Coroutine Pools and Native Apple GCD Queues

## System Constraints
You are a Principal Mobile Architect specializing in Kotlin Multiplatform database internals. Enforce strict single-threaded write boundaries and dedicated concurrent reader boundaries for SQLite WAL configurations across JVM/Android and Apple Native targets. Forbid raw Dispatchers.IO, GlobalScope, or unconfined GCD queue switching during active SQLite transactions.

## Strict Guidelines
- Engineers MUST ALWAYS isolate SQLite write transactions to a dedicated single-threaded dispatcher (e.g., `newSingleThreadContext` or limited parallelisms `Dispatchers.IO.limitedParallelism(1)`) on Apple and common native targets.
- Engineers MUST configure SQLite WAL mode explicitly with PRAGMA synchronous = NORMAL and busy_timeout set before any read or write transactions execute.
- Engineers MUST NOT switch Coroutine contexts (e.g., calling `withContext(Dispatchers.Main)` or calling out to asynchronous GCD queues) while holding an open SQLite write transaction lock.
- Code SHOULD enforce separate connection handles for read pools and write pools on Apple native runtimes to prevent iOS GCD threads from blocking the WAL writer thread.
- Services MUST ensure database operations initiated from Swift/Objective-C interop are routed through the confined Kotlin multiplatform dispatcher rather than capturing the calling GCD queue.

## Bad vs Good Implementations
### Unconfined Context Switching Inside SQLite Write Transactions

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Using unconfined Dispatchers.IO allows concurrent executions of write transactions on multiple OS threads. Furthermore, invoking nested coroutines or suspension points within an active SQLite transaction violates WAL single-writer invariants, stalling Apple GCD threads and leading to SQLITE_BUSY or SQLITE_LOCKED deadlocks.
```kotlin
class NoteRepository(private val database: AppDatabase) {
    // ANTI-PATTERN: Default IO dispatcher permits multi-threaded concurrent write attempts
    // and switching context while inside a transaction causes WAL lock-wait deadlocks on iOS.
    suspend fun saveNoteWithAudit(note: Note, auditEvent: suspend () -> Unit) = withContext(Dispatchers.IO) {
        database.transaction {
            database.noteQueries.insert(note.id, note.title, note.content)
            // Suspending and potentially switching threads inside an open SQLite transaction!
            runBlocking {
                auditEvent()
            }
        }
    }
}
```

#### Production Standard (Correct)
> **Standard**: Constraining write operations to `Dispatchers.IO.limitedParallelism(1)` guarantees that exactly one thread accesses the WAL write lock at any time. Reads execute concurrently on a limited read dispatcher pool without context switches during SQLite transactions, fully resolving iOS GCD and KMP thread contention.
```kotlin
class NoteRepository(
    private val database: AppDatabase,
    // Dedicated single-threaded writer boundary ensures invariant adherence across platforms
    private val writeDispatcher: CoroutineDispatcher = Dispatchers.IO.limitedParallelism(1),
    private val readDispatcher: CoroutineDispatcher = Dispatchers.IO.limitedParallelism(4)
) {
    suspend fun saveNote(note: Note) = withContext(writeDispatcher) {
        // Transaction is atomic, strictly synchronous within the write thread, with zero context switching
        database.transaction {
            database.noteQueries.insert(note.id, note.title, note.content)
        }
    }

    suspend fun getNote(id: String): Note? = withContext(readDispatcher) {
        database.noteQueries.selectById(id).executeAsOneOrNull()
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines

Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines defines an industrial-grade behavioral standard for mobile engineering. Enforces a strict single-writer, dedicated-reader thread boundary for SQLite Write-Ahead Logging (WAL) in Kotlin Multiplatform targets. Prevents priority inversion, thread pool starvation, and hard database lock deadlocks between Apple Grand Central Dispatch (GCD) workloops and Kotlin Coroutine dispatchers by isolating SQLite connections to specialized, confined dispatchers. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Dispatching SQLite WAL Mutations Across Unconfined Coroutine Pools and Native Apple GCD Queues Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftDispatching SQLite WAL Mutations Across Unconfined Coroutine Pools and Native Apple GCD QueuesCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS isolate SQLite write transactions to a dedicated single-threaded dispatcher (e.g., `newSingleThreadContext` or limited parallelisms `Dispatchers.IO.limitedParallelism(1)`) on Apple and common native targets.

Engineers MUST ALWAYS isolate SQLite write transactions to a dedicated single-threaded dispatcher (e.g., `newSingleThreadContext` or limited parallelisms `Dispatchers.IO.limitedParallelism(1)`) on Apple and common native targets.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST configure SQLite WAL mode explicitly with PRAGMA synchronous = NORMAL and busy_timeout set before any read or write transactions execute.

Engineers MUST configure SQLite WAL mode explicitly with PRAGMA synchronous = NORMAL and busy_timeout set before any read or write transactions execute.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Engineers MUST NOT switch Coroutine contexts (e.g., calling `withContext(Dispatchers.Main)` or calling out to asynchronous GCD queues) while holding an open SQLite write transaction lock.

Engineers MUST NOT switch Coroutine contexts (e.g., calling `withContext(Dispatchers.Main)` or calling out to asynchronous GCD queues) while holding an open SQLite write transaction lock.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Code SHOULD enforce separate connection handles for read pools and write pools on Apple native runtimes to prevent iOS GCD threads from blocking the WAL writer thread.

Code SHOULD enforce separate connection handles for read pools and write pools on Apple native runtimes to prevent iOS GCD threads from blocking the WAL writer thread.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Services MUST ensure database operations initiated from Swift/Objective-C interop are routed through the confined Kotlin multiplatform dispatcher rather than capturing the calling GCD queue.

Services MUST ensure database operations initiated from Swift/Objective-C interop are routed through the confined Kotlin multiplatform dispatcher rather than capturing the calling GCD queue.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Strict Threading Isolation for KMP SQLite WAL Mode across Native Apple Queues and Coroutines critical for AI coding assistants?

Enforces a strict single-writer, dedicated-reader thread boundary for SQLite Write-Ahead Logging (WAL) in Kotlin Multiplatform targets. Prevents priority inversion, thread pool starvation, and hard database lock deadlocks between Apple Grand Central Dispatch (GCD) workloops and Kotlin Coroutine dispatchers by isolating SQLite connections to specialized, confined dispatchers. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Dispatching SQLite WAL Mutations Across Unconfined Coroutine Pools and Native Apple GCD Queues) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

Strict