This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-sqlite-atomic-mutex-concurrency-invariant

KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant

Enforces strict serialized write dispatching, proper WAL journal mode initialization, and atomic inter-process file locking across Kotlin Multiplatform targets. Prevents catastrophic SQLite corruption, POSIX lock poisoning, and unrecoverable SQLITE_BUSY deadlocks between background workers (Android WorkManager, iOS BGAppRefreshTask) and foreground UI threads.

Prohibited Anti-Pattern: Uncoordinated Multi-Handle SQLite Writes and Missing WAL PRAGMA Mutex in KMP Background Workers

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant - Enforces strict serialized write dispatching, proper WAL journal mode initialization, and atomic inter-process file locking across Kotlin Multiplatform targets. Prevents catastrophic SQLite corruption, POSIX lock poisoning, and unrecoverable SQLITE_BUSY deadlocks between background workers (Android WorkManager, iOS BGAppRefreshTask) and foreground UI threads.
globs: **/commonMain/**/*.kt, **/iosMain/**/*.kt, **/androidMain/**/*.kt, **/*Database*.kt, **/*Driver*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-sqlite-atomic-mutex-concurrency-invariant"
---

# KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Uncoordinated Multi-Handle SQLite Writes and Missing WAL PRAGMA Mutex in KMP Background Workers

## System Constraints
You are a Principal Mobile Systems Architect and Rules Author enforcing atomic file mutexes and SQLite concurrency invariants across Kotlin Multiplatform (Android & iOS). You must reject any direct un-synchronized database initialization, missing WAL/busy_timeout PRAGMAs, uncoordinated cross-process access between host apps and App Extensions / Background Tasks, and concurrent write-transaction execution across coroutine dispatchers.

## Strict Guidelines
- Engineers MUST ALWAYS configure SQLite connections with PRAGMA journal_mode = WAL; PRAGMA busy_timeout = 5000; and PRAGMA synchronous = NORMAL; upon raw connection creation across all platform targets.
- Engineers MUST ALWAYS serialize all mutating transactions through a single-threaded dispatcher or an explicit FIFO kotlinx.coroutines.sync.Mutex when accessing the database in shared KMP code.
- Engineers MUST NOT instantiate independent SQLite driver instances targeting the same database file within the same process; a single singleton driver instance per database path MUST be maintained.
- Code targeting iOS App Extensions (WidgetKit, Notification Service) sharing an App Group SQLite database with the main app MUST acquire a POSIX advisory file lock (flock/fcntl) or Darwin NSFileCoordinator lock before entering any write transaction.
- Background worker routines (WorkManager on Android, BGProcessingTask on iOS) MUST NEVER execute indefinite blocking transactions; they MUST implement cooperative cancellation and handle SQLITE_BUSY / SQLiteDatabaseLockedException with exponential backoff and jitter.
- Services MUST explicitly close connections or finalize prepared statements before background task execution is suspended by the OS runtime to avoid holding POSIX byte-range file locks while suspended.

## Bad vs Good Implementations
### KMP SQLite Driver Instantiation and Serialized Transaction Gate

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Creating unconfigured raw drivers defaults to DELETE rollback journal mode, which blocks concurrent readers during writes. Executing transactions across Dispatchers.Default allows concurrent writes on separate threads, leading directly to SQLITE_BUSY, database locking exceptions, or database corruption during mobile background execution preemption.
```kotlin
// Anti-Pattern: Unsynchronized independent driver creation with default rollback journal
class DatabaseProvider(private val context: Any?) {
    fun createDriver(): SqlDriver {
        // Direct instantiation without PRAGMA journal_mode=WAL or busy_timeout configuration
        // Invoking multiple writes concurrently across dispatchers yields SQLITE_BUSY or disk I/O deadlocks
        return NativeSqliteDriver(Schema, "app_data.db")
    }
}

class Repository(private val driver: SqlDriver) {
    suspend fun performBackgroundSync(items: List<Item>) = withContext(Dispatchers.Default) {
        // Violates Single-Writer invariant: Concurrent calls on Dispatchers.Default execute parallel write transactions
        driver.execute(null, "BEGIN TRANSACTION", 0)
        items.forEach { item ->
            driver.execute(null, "INSERT OR REPLACE INTO items VALUES (${item.id}, '${item.value}')", 0)
        }
        driver.execute(null, "COMMIT", 0)
    }
}
```

#### Production Standard (Correct)
> **Standard**: Configures mandatory SQLite PRAGMAs (WAL mode, busy_timeout, synchronous=NORMAL) and routes all mutating operations through an explicit atomic coroutine Mutex confined to a serialized single-thread executor. This guarantees no concurrent writes collide across dispatchers or background worker threads.
```kotlin
// Production Fix: Enforced Single-Writer Mutex, WAL mode, busy_timeout, and serialized execution
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext
import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.Executors

interface DatabaseMutexGate {
    suspend fun <T> withWriteLock(block: suspend () -> T): T
}

class AtomicDatabaseGate : DatabaseMutexGate {
    private val writeMutex = Mutex()
    // Confine native SQLite writes to a dedicated single thread to guarantee serialized posix locking
    private val writeDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher()

    override suspend fun <T> withWriteLock(block: suspend () -> T): T {
        return writeMutex.withLock {
            withContext(writeDispatcher) {
                block()
            }
        }
    }
}

fun configureSqliteConnection(rawConnection: Any) {
    // Native hook or SQLDelight Callback must apply baseline invariants immediately on connection hook
    // 1. journal_mode = WAL allows concurrent reads during writes
    // 2. busy_timeout = 5000 gives workers time to wait for active readers/writers
    // 3. synchronous = NORMAL ensures crash durability with low IO latency in WAL mode
    val pragmas = listOf(
        "PRAGMA journal_mode = WAL;",
        "PRAGMA busy_timeout = 5000;",
        "PRAGMA synchronous = NORMAL;"
    )
    // Execute PRAGMAs on raw handle before exposing to ORM/repository layers
}

class SafeRepository(
    private val database: AppDatabase,
    private val gate: DatabaseMutexGate
) {
    suspend fun performBackgroundSync(items: List<Item>) = gate.withWriteLock {
        database.transaction {
            items.forEach { item ->
                database.itemQueries.insertOrReplace(item.id, item.value)
            }
        }
    }
}
```

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: KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant

KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant defines an industrial-grade behavioral standard for mobile engineering. Enforces strict serialized write dispatching, proper WAL journal mode initialization, and atomic inter-process file locking across Kotlin Multiplatform targets. Prevents catastrophic SQLite corruption, POSIX lock poisoning, and unrecoverable SQLITE_BUSY deadlocks between background workers (Android WorkManager, iOS BGAppRefreshTask) and foreground UI threads. 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: Uncoordinated Multi-Handle SQLite Writes and Missing WAL PRAGMA Mutex in KMP Background Workers 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 DriftUncoordinated Multi-Handle SQLite Writes and Missing WAL PRAGMA Mutex in KMP Background WorkersCritical
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 configure SQLite connections with PRAGMA journal_mode = WAL

Engineers MUST ALWAYS configure SQLite connections with PRAGMA journal_mode = WAL; PRAGMA busy_timeout = 5000; and PRAGMA synchronous = NORMAL; upon raw connection creation across all platform 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 ALWAYS serialize all mutating transactions through a single-threaded dispatcher or an explicit FIFO kotlinx.coroutines.sync.Mutex when accessing the database in shared KMP code.

Engineers MUST ALWAYS serialize all mutating transactions through a single-threaded dispatcher or an explicit FIFO kotlinx.coroutines.sync.Mutex when accessing the database in shared KMP code.

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 instantiate independent SQLite driver instances targeting the same database file within the same process

Engineers MUST NOT instantiate independent SQLite driver instances targeting the same database file within the same process; a single singleton driver instance per database path MUST be maintained.

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 targeting iOS App Extensions (WidgetKit, Notification Service) sharing an App Group SQLite database with the main app MUST acquire a POSIX advisory file lock (flock/fcntl) or Darwin NSFileCoordinator lock before entering any write transaction.

Code targeting iOS App Extensions (WidgetKit, Notification Service) sharing an App Group SQLite database with the main app MUST acquire a POSIX advisory file lock (flock/fcntl) or Darwin NSFileCoordinator lock before entering any write transaction.

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

Background worker routines (WorkManager on Android, BGProcessingTask on iOS) MUST NEVER execute indefinite blocking transactions

Background worker routines (WorkManager on Android, BGProcessingTask on iOS) MUST NEVER execute indefinite blocking transactions; they MUST implement cooperative cancellation and handle SQLITE_BUSY / SQLiteDatabaseLockedException with exponential backoff and jitter.

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.
6

Services MUST explicitly close connections or finalize prepared statements before background task execution is suspended by the OS runtime to avoid holding POSIX byte-range file locks while suspended.

Services MUST explicitly close connections or finalize prepared statements before background task execution is suspended by the OS runtime to avoid holding POSIX byte-range file locks while suspended.

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 KMP Multiplatform Atomic File Mutex & Concurrent SQLite Lock Invariant critical for AI coding assistants?

Enforces strict serialized write dispatching, proper WAL journal mode initialization, and atomic inter-process file locking across Kotlin Multiplatform targets. Prevents catastrophic SQLite corruption, POSIX lock poisoning, and unrecoverable SQLITE_BUSY deadlocks between background workers (Android WorkManager, iOS BGAppRefreshTask) and foreground UI threads. 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 (Uncoordinated Multi-Handle SQLite Writes and Missing WAL PRAGMA Mutex in KMP Background Workers) 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

KMP