<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5" -->

---
title: Two waiters. One order. One disaster. | daily.dev
description: Using a restaurant analogy, this post explains race conditions and shared state problems in Go's concurrency model. When multiple goroutines access the same...
canonical: https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Two waiters. One order. One disaster. | daily.dev
og:description: Using a restaurant analogy, this post explains race conditions and shared state problems in Go's concurrency model. When multiple goroutines access the same...
og:url: https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5
og:image: https://api.daily.dev/og/posts/7hJQWt8e5.png
og:image:alt: Two waiters. One order. One disaster.
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Two waiters. One order. One disaster.

**[Medium](https://daily.dev/sources/medium_js)** · 4 min read · 0 upvotes · 0 comments

## Summary

Using a restaurant analogy, this post explains race conditions and shared state problems in Go's concurrency model. When multiple goroutines access the same variable without coordination, conflicting writes can corrupt data — illustrated with a bank account losing updates. The solution is sync.Mutex, which enforces mutual exclusion so only one goroutine accesses a shared resource at a time. The key insight is that mutexes ensure correctness, not speed, and locking too broadly can serialize what was meant to be concurrent. The discipline lies in locking at the right granularity and releasing as soon as possible.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@sundayprincedev/two-waiters-one-order-one-disaster-4649a51fb70b>

## Questions this post answers

### How do I fix a race condition when two goroutines write to the same shared variable in Go?

Use sync.Mutex to enforce exclusive access to the shared resource. Call Lock() before reading or writing the shared state and Unlock() when done; any other goroutine calling Lock() on the same mutex will wait until it is released, preventing simultaneous reads and writes like the classic lost-update bug where two withdrawals both read a stale balance.

_Developers debugging goroutine race conditions can find deeper concurrency patterns and discussions on daily.dev._

### Does using a mutex in Go make concurrent code faster?

No, a mutex does not make code faster, it makes it correct. Locking too broadly, such as locking an entire transaction system instead of just the account balance field, serializes what was meant to run concurrently, turning parallel goroutines into a queue of one and potentially making the system slower than without goroutines at all.

_Anyone tuning goroutine performance can weigh locking strategies and trade-offs shared on daily.dev._

## Similar posts on daily.dev

- [It's a lock: sync.Mutex in Go — Bitfield Consulting](https://daily.dev/posts/it-s-a-lock-sync-mutex-in-go-bitfield-consulting-tsdpezd8o) · Bitfield Consulting · 34 upvotes · 0 comments
- [Racing with disaster: data races in Go — Bitfield Consulting](https://daily.dev/posts/racing-with-disaster-data-races-in-go-bitfield-consulting-d9aa7sqwr) · Bitfield Consulting · 21 upvotes · 0 comments
- [A million ways to die from a data race in Go](https://daily.dev/posts/a-million-ways-to-die-from-a-data-race-in-go-z5xebrrg7) · Hacker News · 1 upvotes · 1 comments
- [Go concurrency distilled](https://daily.dev/posts/go-concurrency-distilled-4hj6bvvyj) · Anton Zhiyanov · 49 upvotes · 2 comments

---

Tags: [#golang](https://daily.dev/tags/golang)

[View this post on daily.dev](https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Two waiters. One order. One disaster.","url":"https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5"},"datePublished":"2026-07-12T12:14:58.180Z","dateModified":"2026-09-14T08:55:50.489Z","description":"Using a restaurant analogy, this post explains race conditions and shared state problems in Go's concurrency model. When multiple goroutines access the same...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/61fca87092df7da9b0616a1bfc6979b5?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/61fca87092df7da9b0616a1bfc6979b5?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"golang","timeRequired":"PT4M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Two waiters. One order. One disaster."}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/two-waiters-one-order-one-disaster--7hjqwt8e5#faq","mainEntity":[{"@type":"Question","name":"How do I fix a race condition when two goroutines write to the same shared variable in Go?","acceptedAnswer":{"@type":"Answer","text":"Use sync.Mutex to enforce exclusive access to the shared resource. Call Lock() before reading or writing the shared state and Unlock() when done; any other goroutine calling Lock() on the same mutex will wait until it is released, preventing simultaneous reads and writes like the classic lost-update bug where two withdrawals both read a stale balance. Developers debugging goroutine race conditions can find deeper concurrency patterns and discussions on daily.dev."}},{"@type":"Question","name":"Does using a mutex in Go make concurrent code faster?","acceptedAnswer":{"@type":"Answer","text":"No, a mutex does not make code faster, it makes it correct. Locking too broadly, such as locking an entire transaction system instead of just the account balance field, serializes what was meant to run concurrently, turning parallel goroutines into a queue of one and potentially making the system slower than without goroutines at all. Anyone tuning goroutine performance can weigh locking strategies and trade-offs shared on daily.dev."}}]}
```

