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:

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:

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:

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.