Search
13 results for “deadlocks”
Search results
Database Locking & Deadlocks
How PostgreSQL's row-level lock modes actually differ in strength, why it can't predict which transaction a deadlock will abort, and why acquiring locks in a consistent order is the real fix, not a "nice to have".
What is the practical difference between SELECT ... FOR UPDATE and SELECT ... FOR SHARE?
FOR UPDATE takes an exclusive row lock, it blocks other transactions from updating, deleting, or taking any competing lock (including another FOR UPDATE or FOR SHARE) on the same rows, appropriate when you're about to modify the row and need to ensure nothing else changes or locks it first. FOR SHARE takes a shared lock, it still blocks updates and deletes, but permits other transactions to also take FOR SHARE or FOR KEY SHARE locks on the same rows concurrently, appropriate when you only need to ensure a row doesn't change or get deleted while you read it, without needing exclusive access.
PostgreSQL detects a deadlock between two transactions. What does it actually do, and can you predict which transaction survives?
PostgreSQL automatically detects the circular wait (a deadlock) and resolves it by aborting one of the involved transactions, letting the other(s) proceed. The documentation is explicit that which transaction gets aborted is difficult to predict and shouldn't be relied upon, there is no guarantee it's the "smaller" transaction, the one that started the wait, or any other predictable rule. Applications need to handle a deadlock-abort the same way they'd handle a serialization failure: catch it and retry the aborted transaction, rather than assuming a specific transaction will always be the one sacrificed.
Two transactions each update two of the same two accounts, but in opposite order, and deadlock. What's the actual fix, not just for this pair of transactions, but for the application generally?
The deadlock happens because Transaction 1 locks account A then waits for account B, while Transaction 2 locks account B then waits for account A, a circular wait. The general fix isn't retry logic alone, retries only paper over deadlocks that keep recurring, it's acquiring locks on multiple objects in the same, consistent order everywhere in the application (for example, always locking accounts in ascending id order), which makes the circular-wait pattern structurally impossible rather than merely less frequent. Retry logic is still worth having as a safety net, but consistent lock ordering is what actually eliminates this class of deadlock.
What is the difference between requirements.txt and a lockfile, and why does it matter for reproducibility?
A typical `requirements.txt` often specifies loose version ranges (`requests>=2.28`), which means two installs at different times can resolve to different actual versions as new releases come out, not truly reproducible. A lockfile (like `poetry.lock` or `uv.lock`) pins the exact resolved version of every dependency and transitive dependency, so installing from it produces the identical dependency tree every time, on any machine. The distinction matters because a subtle bug caused by a transitive dependency's patch version can be nearly impossible to reproduce without a lockfile guaranteeing everyone has the exact same versions.
What is a shard key, and why does a low-cardinality shard key (few distinct values) cause a hot shard?
A shard key is the field (or fields) a sharded database uses to decide which shard each document or row actually lives on. If that field has few distinct values, say `country`, and the real data is skewed (80% of users in one country), the vast majority of documents route to the same shard regardless of how many shards exist in the cluster, overwhelming it with disproportionate read/write load and storage while other shards sit comparatively idle. Cardinality alone doesn't guarantee even distribution either, the values also need to actually occur with reasonably even frequency in the real data, not just theoretically have many possible values.
When does semantic search (via embeddings) actually outperform traditional keyword search, and when might keyword search still win?
Semantic search wins when a query and the relevant document use different words for the same idea, "car won't start" matching a document about "vehicle fails to ignite", since embeddings compare meaning rather than literal tokens, which keyword search cannot do at all. Keyword search still wins, or at least remains necessary, for exact-match needs, an error code, a product SKU, a specific proper noun, where the literal string matters and a semantically "close" but textually different result is actually the wrong answer. This is why production search systems commonly combine both (hybrid search) rather than treating embeddings as a strict replacement for keyword matching.
What does it mean for a secret to be "dynamic" or "short-lived," and why does that reduce risk compared to a long-lived static credential?
A dynamic secret is issued on demand, scoped to a single application instance or session, and expires automatically after a defined lease, a database credential minted when a service starts and revoked automatically when it stops, rather than a password typed in once and left valid indefinitely. If a short-lived secret leaks, its usefulness to an attacker is bounded by its remaining lease time, often minutes, instead of remaining valid until someone notices and manually rotates it. This is the same underlying idea as preferring IAM roles over long-lived access keys in a cloud provider, temporary credentials shrink the blast radius of a leak by construction, not by better hiding the secret.
Why does Python use indentation instead of braces to define code blocks, and what problem does this create?
Python uses indentation as syntax specifically to force a consistent visual structure, code that looks nested is nested, with no possibility of a brace mismatch making the visual and actual structure disagree, a real class of bugs in brace-delimited languages. The trade-off is that whitespace becomes semantically meaningful: mixing tabs and spaces, or an accidentally misaligned line, is a syntax error (or worse, silently changes which block a line belongs to) rather than a cosmetic issue. Python 3 disallows mixing tabs and spaces in the same file specifically to prevent the silent version of this problem.
Why would a system use a sliding window rate limiter instead of a token bucket, and what problem does it fix?
A naive fixed window (say, "100 requests per minute, resetting on the minute") allows a client to send 100 requests in the last second of one window and another 100 in the first second of the next, 200 requests in a two-second span despite the stated 100/minute limit, an artifact of the window boundary rather than actual demand. A sliding window rate limiter instead evaluates the limit over a continuously moving time range rather than fixed, discrete buckets, which avoids that boundary-doubling effect at the cost of typically more state to track (timestamps of recent requests, not just a single counter) compared to a token bucket's simpler accumulator model.
What is the difference between a reserved/committed-use discount and a spot/preemptible instance, and when does each make sense?
A committed-use discount (reserved instances, savings plans) trades a usage commitment, a fixed amount of spend or capacity over a term, typically one or three years, for a significant price reduction on workloads you know will run continuously. Spot/preemptible instances offer a much steeper discount in exchange for the provider being able to reclaim the capacity with little notice, making them suitable only for interruption-tolerant workloads (batch jobs, stateless workers, CI runners) rather than anything requiring guaranteed uptime. Committed-use addresses predictable steady-state load; spot addresses flexible, interruption-tolerant load, using either for the wrong workload type either wastes the discount or causes outages.
What is the difference between durability and availability in S3, and why does it matter when picking a storage class?
Durability is the probability that a stored object is not lost over a year, and S3 Standard, Standard-IA, and every Glacier class are all designed for the same 99.999999999% (11 nines) durability. Availability is how often the object can actually be successfully retrieved on demand, and that number does vary by class, 99.99% for Standard down to 99.5% for One Zone-IA. It matters because a cheaper class is not automatically a less durable one, S3 One Zone-IA is exactly as durable as Standard-IA per object, but it is not resilient to the loss of its single Availability Zone at all, since it isn't replicated across multiple zones the way every multi-AZ class is.
A client sends a payment request, the network times out before a response arrives, and the client retries with the same idempotency key. What actually happens on the server?
If the original request already completed (successfully or even with an error like a 500) before the retry arrives, the server returns the exact same result it returned (or would have returned) the first time, the same status code and response body, without re-executing the underlying operation, so the customer isn't charged twice just because the client never saw the first response. This is the entire point of an idempotency key: it lets a client safely retry an operation whose actual outcome it's genuinely uncertain about (did the first request even reach the server? did it complete before the timeout?) without that retry risking a duplicate side effect.