You built it for three people. Maybe five. Now fifteen people are in the database at the same time, and things are falling apart. Forms freeze. Records vanish. Someone gets a “write conflict” error and loses twenty minutes of data entry.
This is not a bug. This is Access working exactly as designed — and hitting the wall it was always going to hit.
The Jet Database Engine Was Not Built for This
Microsoft Access uses the Jet database engine (or its successor, ACE)
to manage data. Unlike SQL Server, MySQL, or PostgreSQL, Jet is a
file-based database engine. There is no server process managing
access to the data. Every user’s copy of Access reads and writes
directly to the same .mdb or .accdb file
sitting on a shared network drive.
When User A saves a record, Access writes bytes directly to the file.
When User B tries to save a different record at the same moment, both
processes are fighting over the same file handle through Windows file
sharing (SMB). The only traffic cop is the .ldb lock file —
a simple mechanism that was designed for light use, not concurrent
production workloads.
This architecture has three consequences that get worse with every user you add.
Problem 1: Record Locking That Does Not Scale
Access supports two locking strategies: optimistic and pessimistic. With optimistic locking, Access only locks the record at the moment of writing. With pessimistic locking, it locks when the user starts editing.
Neither works well past about 10-15 concurrent users. Here is why:
- Lock granularity is page-based, not row-based. Access locks a 4KB page at a time, which typically contains multiple records. If User A edits row 47, rows 45 through 52 might all become locked — even though nobody asked to lock those rows.
- Lock information travels over SMB. Every lock check is a network round-trip to the file server. As users increase, these round-trips stack up and response times climb.
- Stale locks accumulate. If a user’s machine crashes
or they disconnect from the network without closing Access, their locks
can remain in the
.ldbfile. Other users then cannot edit those records until someone manually clears the lock file.
The result: write conflicts, mysterious delays, and the occasional total lock-up that requires everyone to close the database.
Problem 2: Network Latency Destroys Performance
When Access runs a query, it does not ask a server to process the query and return results. Instead, it pulls raw data pages across the network and processes them locally. A query that joins three tables might transfer megabytes of data over your LAN just to return ten rows.
With a few users, you do not notice. With fifteen users all running queries, reports, and form loads at the same time, the network traffic multiplies. A query that took two seconds with three users now takes thirty seconds — or times out entirely.
This is also why Access databases perform terribly over VPN connections. The Jet engine was designed for low-latency local area networks. Introduce 50ms of latency and everything slows to a crawl.
Problem 3: Corruption Is Not a Matter of If, But When
File-based databases are inherently fragile under concurrent access.
Every one of these scenarios can corrupt your .accdb
file:
- A user’s machine crashes mid-write
- The network connection drops during a save
- Windows updates restart a workstation while Access is open
- A power flicker hits the file server
- Someone opens the file directly from a mapped drive while another user has it open via UNC path
With a single user, corruption is rare. With fifteen users across an eight-hour workday, you are rolling the dice hundreds of times. The standard advice — “run Compact and Repair weekly” — is an admission that corruption is expected, not exceptional.
A server-based database like SQL Server or PostgreSQL does not have this problem. The server process manages all writes through a transaction log with write-ahead logging (WAL). If a client crashes mid-transaction, the server rolls it back cleanly. The data file is never exposed to network file sharing hazards.
The 2GB Ceiling Makes It Worse
Access databases have a hard limit of 2GB per .accdb
file. That sounds like a lot until you realize that OLE Object fields,
attached images, and audit logging can eat through that space fast. Once
you are past about 1.5GB, performance degrades noticeably as Access
struggles to find contiguous space for new records.
There is no warning when you approach the limit. Access just starts throwing errors — or silently corrupting data.
So What Do You Do?
If you are seeing these symptoms, you have outgrown Access as a back-end database. The good news: you do not necessarily have to throw away everything. The most common migration path is to keep your Access forms and reports as the front-end while moving the data to a proper database server. This is called “upsizing” and it is the least disruptive option.
Your main choices for a back-end database are:
- SQL Server — easiest if you are already in the Microsoft ecosystem. Access has built-in tools (ODBC linked tables) that make the connection straightforward.
- MySQL — popular open-source option with broad hosting support. Good if cost is a factor.
- MariaDB — a MySQL-compatible fork with additional features and no Oracle licensing concerns.
- PostgreSQL — the most standards-compliant option with the best data integrity features. Steeper learning curve but the most capable long-term choice.
Each option has trade-offs in cost, complexity, and compatibility with your existing VBA code. The right choice depends on your team’s skills, your budget, and how far you want to go with the migration.
The Bottom Line
Access is not a bad tool. It is a prototyping and small-team tool that gets pressed into service as a production database because it is easy to start with. The problems you are seeing at 15 users are not fixable with better hardware, faster networks, or clever VBA workarounds. They are architectural limitations of a file-based database engine.
The fix is moving your data to a database that was designed for concurrent access from the ground up. The only question is which one — and how to get there without breaking your business in the process.