Privacy checks, SSH escapes and power cuts · Morning Gist
Wednesday, October 285 stories · 15 min
Privacy checks, SSH escapes and power cuts
Today's stories cover where checks belong in a system and where things fail: Meta's data stores, Tailscale's SSH, the Internet's power supply and Python's type checkers.
Picked from 70 new articles across 34 sources · arrow keys for other days
Today in 30 seconds
30s left
Meta's PrivacyLib puts privacy checks in every data store's client. New rules ship as modules, are tested by replaying real flows and roll out by percentage. story 1 ↓
Tailscale 1.104.4 fixes SSH bugs that let logged-in users exceed their privileges, plus three Serve/Funnel bugs. The researcher gave two hours' notice. story 2 ↓
Cloudflare logged 49 Internet disruptions in Q3, mostly from power failures and Iraq's exam shutdowns. One facility's outage cut Honduras's traffic by 63%. story 3 ↓
PlanetScale traces how Postgres went from near-abandonment in 1994, through Heroku's 2011 pick, to leading MySQL in a 2023 survey. story 4 ↓
Python Typing Survey: type hint use is flat, half of 1,794 respondents run more than one checker, and 65.1% cite untyped libraries. story 5 ↓
1/5Engineering at Meta· Oct 27
Meta's PrivacyLib runs privacy checks inside the client of every data store
Meta built PrivacyLib, a library inside the clients of hundreds of data systems that checks every read and write against privacy rules. It runs billions of checks per second, mostly answered from in-process caches.
Why it matters · It shows how to put a policy check on every data access across many teams' systems: one shared seam, a fast path that stays in-process, and per-service rollback.
Know this first
Context from the editor, not the article · 36 sec
1 · Privacy Aware Infrastructure
Meta's Privacy Aware Infrastructure (PAI) builds privacy rules into its storage and processing systems so they don't depend on manual audits. Earlier posts covered classifying data, tracking where data flows (lineage), and Policy Zones, Meta's information flow control system. PrivacyLib is the final stage, where rules are enforced and monitored at runtime.
2 · Purpose limitation, flow control
Purpose limitation means data collected for one purpose may only be used for approved purposes. Information flow control enforces this by tagging data with labels and checking, at every move, whether the current context is allowed to send labelled data to a given destination.
3 · Client-side vs server-side checks
2/5Tailscale· Mike Shaver· Oct 28
Tailscale patches SSH flaws that let logged-in users exceed their privileges
A researcher's "Tailworm" report showed that Tailscale's built-in SSH server did not fully confine sessions to the local user they were granted. Tailscale shipped fixes in v1.104.4 and says an attacker needed an authorized foothold first.
Why it matters · Any root process that hands out unprivileged sessions faces the same problem. This case shows that checking who may connect is a separate job from limiting what they can do afterwards.
Know this first
Context from the editor, not the article · 34 sec
1 · Tailscale and tailnets
Tailscale builds a private mesh network, called a tailnet, on top of the WireGuard VPN protocol. Devices sign in with an identity provider. A central policy file, a set of access-control rules, decides which users and devices may reach which machines and ports.
2 · Privileged SSH servers
An SSH server runs as root so it can start sessions as different Unix users. Once a user is authorized, the server must drop to that user's permissions for everything the session does, including shells, file access and port or socket forwarding. OpenSSH's long-standing 'privilege separation' design exists for exactly this reason.
3 · Lateral movement
3/5Cloudflare· Lai Yi Ohlsen· Oct 27
Power failures and Iraq's exam shutdowns drove Q3 2026 Internet outages
Cloudflare's traffic monitor recorded 49 Internet disruptions between July and September 2026. Iraq's exam shutdowns made government orders the top cause, power outages came second, and earthquakes, floods and typhoons accounted for five.
Why it matters · The incidents show where Internet redundancy breaks down in practice: shared power, shared exchange buildings and cooling. The same single points of failure exist inside any distributed system's dependency graph.
Know this first
Context from the editor, not the article · 34 sec
1 · How Radar sees outages
Cloudflare Radar is Cloudflare's public traffic dashboard. Cloudflare serves over 20% of web traffic, so when requests from a country, region or network suddenly fall below their usual pattern, Radar flags and labels a disruption. It measures lost demand. It cannot see the cause directly.
2 · Autonomous systems
The Internet is made of tens of thousands of independently run networks called autonomous systems (ASes), each with a number such as AS3816. Breaking traffic down by AS shows which providers failed and which kept working, which hints at how each one is wired.
3 · Interconnection points
4/5PlanetScale· Simeon Griggs· Oct 27
Postgres became the default database in steps, not one turning point
PlanetScale's Simeon Griggs works backward through Postgres's history to find when it became the default database. The milestones are 1996, 2010, 2011, 2014 and 2023. He names no single winner, and some of the luck was accidental.
Why it matters · Knowing why an ecosystem won, through licensing, governance, hosting convenience and extensibility, helps you judge which technologies will last when you choose a stack for a decade.
Know this first
Context from the editor, not the article · 33 sec
1 · The two open-source rivals
MySQL and PostgreSQL (Postgres) are the two dominant open-source relational databases. MySQL ran most of the early web, the M in the LAMP stack. Postgres had a reputation for correctness, full transactions and complex queries, but for years it trailed MySQL in adoption.
2 · Who is telling this story
PlanetScale is a hosted-database company. It built its business on Vitess, YouTube's system for sharding MySQL, and it now sells Postgres too. The essay comes from its blog and includes product plugs, so its framing is not neutral.
3 · How popularity gets measured
5/5Engineering at Meta· Oct 27
Python Typing Survey 2026: type hint use holds steady, checker choice fragments
Meta and other checker teams surveyed 1,794 Python developers. About 86% use type hints often, the same as in past years. But many moved to newer, faster checkers, half now run several, and library typing gaps remain the biggest problem.
Why it matters · If your team runs Python at scale, picking a checker, coping with untyped libraries and handling disagreements between tools are now real decisions with real costs.
Know this first
Context from the editor, not the article · 29 sec
1 · Python type hints
Since Python 3.5, code can carry optional annotations like def f(x: int) -> str. The interpreter ignores them at runtime. Separate static type checkers read them and report mismatches before the code runs, much like a compiler would.
2 · The checker field
Mypy, the original checker, is written in Python and supports plugins. Pyright (Microsoft) powers VS Code's Python tooling. Two newer checkers written in Rust are Pyrefly (Meta) and ty (Astral). Each reads the typing specification a little differently.
3 · Stubs for libraries
Libraries without inline annotations can ship stub files () that contain only type signatures. Some are maintained separately, such as pandas-stubs. Without stubs, a checker treats library calls as untyped, so the checker can't catch errors there.
An access check can run in the caller's client library or on the shared datastore. The client still knows who is calling, from which endpoint, and why. The datastore sees only the incoming request, and a bug there affects every caller at once.
Before and after: per-system privacy implementations replaced by one shared library with plug-in modules.1 / 4
Meta has published how PrivacyLib works. It is a library embedded in the client libraries of hundreds of its data and processing systems, and it checks every data access against privacy rules. It runs across thousands of services and performs billions of checks per second.
The problem
Many privacy requirements come down to one question: can Meta prove a piece of data goes only where it's allowed? Previously, each requirement, such as 1 (data used only for approved purposes), was written separately into each system's client. Rolling one out took months.
Integrate once, add modules
Each system now maps its APIs onto five common operations: read, write, RPC, request entry, and inline execution, which wraps a single computation inside a request. Requirements are written as modules against those operations. Enforcing modules, such as 2 (Meta's information flow control system), can block an access. Observing modules, such as 3, only record it. Enabling a module on a system that is already integrated takes days.
The check runs in the client, not on the datastore. The client still knows the caller, the endpoint and the purpose, and a bad change affects only the service running that build.
Example: messaging metadata
Messenger backends write delivery metadata to warehouse tables through 4, an in-process logging client. The table's config tags it MESSAGING_TRAFFIC_METADATA once, at the destination, so the many writers can't disagree about it. Code generation turns the config into a PrivacyLib artifact. On each write, Policy Zones checks that the current context is an allowed use of messaging metadata and that the destination carries the tag. If either check fails, the record is blocked before it leaves the process.
Speed and coverage
Rules are compiled at build time, and most checks are answered from per-request and per-host caches. An earlier design's remote config fetch was thousands of times slower. Callers that skip the client and send raw RPCs are checked at the RPC layer. If an earlier client check passed, it attached a signed token that this layer validates. Without the token, the layer applies a stricter, coarser check.
Safe rollout
Annotation changes are tested during code review by replaying observed data flows against the old and new artifacts and reporting any decision that changes. They then ship through each service's own deployment pipeline. That is slower than a global push but limits the damage if something is wrong. New modules start in a rollout mode behind a runtime percentage that can be dialed down without redeploying. Meta admits an early invalid config crashed processes across the fleet.
The same machinery now covers internal agents' tool calls, which carry session context through to PrivacyLib. The post gives no per-check latency or cost figures.
Meta has described PrivacyLib, a shared library that runs inside the client libraries of hundreds of its data and processing systems. It checks data accesses against privacy requirements at the moment they happen. The scale is large: more than a hundred client libraries, from key/value stores to feature systems; thousands of production services running some version of the library; millions of assets accessed daily; and billions of checks per second.
The problem: same logic, built N times
The question behind many privacy requirements is whether Meta can prove that a piece of data goes only where it is allowed. Before PrivacyLib, each new requirement was written separately into the client of each system, so rolling one out across systems could take months. Every requirement, whether 1 or data flow discovery, needed the same things: wide coverage, deployment in weeks, low latency on every access, and safe rollout.
PrivacyLib keeps system integration separate from the requirements themselves. Each system integrates once. Requirements that can be checked at the point of access become modules that reuse that integration. There are two kinds:
Enforcing modules can block an access. 2, Meta's information flow control system, is the main one, and it enforces purpose limitation.
Observing modules only record. 3 collects runtime signals used to discover data flows.
A common execution model
Systems as different as graph databases, filesystems, ML pipelines and loggers each map their native APIs onto five common operations: read, write, RPC (calling another service), request entry (runs once when a service begins handling a request), and inline execution, which wraps a computation such as evaluating a feature. Reads, writes and RPCs also have post-operation hooks so observers can run after the decision. Modules are written against these five operations rather than each system's API. That is why Meta says enabling a new module on an already-integrated system takes days, not months.
Meta gives two reasons for running in the client rather than on the datastore. The client still has rich context: caller identity, endpoint and purpose, which is often lost by the time a request reaches storage. It also isolates failures: a bad change affects only the service running that build, and the shared datastore stays outside the failure boundary.
Worked example: messaging metadata into the warehouse
Messenger's backend processes non-content metadata, such as when messages were sent or delivered, for performance work and abuse detection. Services write it to warehouse tables through 4, an in-process logging client.
Annotating the destination. Each Logger table has a LoggerConfig. The message-delivery trace config pulls in MessagingTrafficMetadataPolicyTrait and calls annotateWithTableLevelPolicy(), which tags the table MESSAGING_TRAFFIC_METADATA. The annotation lives on the destination, not on each writer. If every writer declared it, the declarations could disagree, or a new writer could leave it out. Logger's code generator turns the config into a PrivacyLib artifact that carries the asset ID and the purpose policy. That artifact is generated in 5, Meta's typed PHP dialect. For C++ and Python, Logger publishes the annotations to a central catalog and PrivacyLib generates the matching artifacts.
Configuring the operation. Logger declares once, for all destinations, that its write operation runs Policy Zones (enforcing, with context propagation) and Telemetry Logging (observing). Adding a module touches this configuration, not the call sites.
Running the check. In C++, Logger builds a PrivacyLibRequest from the config name, a hashed API identifier, the caller, and the write implementation, then calls dispatch(). Policy Zones checks two conditions: the current processing context is an allowed use of messaging metadata, and the destination carries the MESSAGING_TRAFFIC_METADATA annotation. If either fails, the module denies the write. PrivacyLib merges the results of all enforcing modules, and a denial stops the record before it leaves the process.
Keeping it cheap
Requirements are compiled at build time into their simplest evaluable form. Per-request caches skip repeated checks within a request, and per-host caches keep hot configuration and results. An earlier design fetched configuration remotely, and Meta says that fetch alone was thousands of times slower than the in-process path. Meta says the fleet-wide cost is "a small fraction" of total compute but gives no latency or CPU figures. Telemetry records each module's status, samples latency and logs errors. Per-host 6 (compact probabilistic sets that cheaply test "seen this before?") downsample high-volume repeated events at a fixed rate, and sampling rates adapt to traffic so rare events stay visible.
Callers that skip the client
Some callers send raw RPCs. When a client-side check passes, PrivacyLib attaches a cryptographically signed token. 7, Meta's RPC routing layer, validates the token on supported traffic, which confirms the richer check already happened. A request with no token gets a coarser check based only on what the network payload shows, using the strictest interpretation: false positives are preferred to gaps. Paths outside Meta-managed clients and supported RPC paths need their own integration.
Rolling out changes
Annotation changes are a two-line edit, but they can start blocking writes from every service that writes to that table. During code review, the generated artifact is rebuilt and a simulation replays observed data flows against both the old and new artifacts, reporting any decision that would change. The code edit, the generated artifact and the simulation diff are reviewed together. The artifact then ships through each service's normal deploy pipeline, so a problem is confined to services running that build. The trade-off is slow propagation compared with a global config push. Owners track which services in scope have updated before a deadline, and services can use emergency deploys if they need the change sooner.
Module rollouts apply to every destination, so a module starts as rollingOut() behind a runtime key (logger.input.write.zones). The key is raised from 0 to 100% in stages while engineers watch denials, errors and latency. It can be lowered without rebuilding anything. Once the module is stable, the config switches to enabled().
Meta is candid about earlier failures. An invalid config once crashed processes across the fleet, and annotation changes that compiled cleanly still changed access decisions and broke products. Its conclusion is that owners trust a hot-path library only when they can see a change's effect beforehand and roll back without a fleet-wide rollback.
Agents, briefly
For internal agents, whose data access isn't known in advance, a sibling runtime called 8 attaches session context to tool calls, and services carry that context through to PrivacyLib. An observing module logs the session and tool-call IDs. Policy Zones then enforces on those calls without modification, whichever tool the agent picks.
Open questions
The post gives no per-check latency, cache hit rates, cost numbers, or false-positive rates for the strict RPC fallback. It also says little about how stale caches interact with annotation changes, or how many services lag behind on old library versions.
Remember
Annotate data at the destination, not per writer, so many writers can't disagree or forget the label.
Checks in the client keep caller context and limit failures to one service; a signed token lets the RPC layer trust earlier checks.
Separate deploy-time changes (shipped per service, simulated first) from runtime percentage dials, so most rollbacks need no fleet-wide action.
An attacker who already controls one machine uses credentials or trust on it to reach other machines. A worm is different: it is malware that copies itself from machine to machine automatically, with no human steering it.
Image: Tailscale
Tailscale has released v1.104.4 to fix flaws in Tailscale SSH and related features. A researcher's public report called "Tailworm" described them last weekend. Mike Shaver's post explains what broke and what an attacker needed beforehand.
The setup
Tailscale runs a private mesh network, a "1," over 2, a VPN protocol. Tailscale SSH is an SSH server built into the Tailscale client. It authenticates users by their Tailscale identity and enforces the 3, the central access rules that say who may log in to which machine and as which local Unix user.
Like OpenSSH, the server runs with elevated privileges so it can start sessions as different users. The hard part is making sure none of that privilege leaks into the session. That covers the shell and also 4, SSH's tunneling of ports and sockets, which the server often carries out on the user's behalf.
What went wrong
Tailscale says the bugs were in that post-login confinement, not in authentication or policy checks. Under certain conditions, an authorized session could act beyond its local user's privileges, including through forwarding. The post doesn't explain how the individual bugs worked.
To exploit them, an attacker first needed a foothold on an authorized device, plus SSH access to the target that the policy already allowed. Shaver argues this is 5, not a worm. Nothing spreads by itself, and attackers could reach only machines the policy already permitted. The flaws widened what a session could do, not where it could go.
The rest of the report
Serve and 6, which share local services with the tailnet or the public internet: of five findings, three were bugs and are fixed. Tailscale says the other two are intended behavior. One needs local admin access; the other, TS_SERVE_ALLOW_ALL_INTERFACES, is an opt-in setting.
7, the unreleased next generation of app connectors: Tailscale already knew about this bug, and says it is one reason Conn25 hasn't shipped.
Timeline
Concerns surfaced on social media on Friday, October 23. Tailscale received the report on Saturday morning, and the researcher published it two hours later. That is far short of the usual coordinated-disclosure window, though Tailscale doesn't criticize it. An update followed on Monday, then v1.104.4 and four bulletins, TS-2026-014 through TS-2026-017. The company also says it added architectural safeguards against whole classes of these bugs, but doesn't describe them.
What to do
Update to v1.104.4 or later. Trim SSH policies to the users and devices that need them, and turn on 8, an extra authentication step, for sensitive hosts.
Tailscale has released v1.104.4 to fix vulnerabilities in Tailscale SSH and related features. A security researcher described them last weekend in a public report called "Tailworm." In a post by Mike Shaver, the company sets out what went wrong, what an attacker needed beforehand, and how it responded. It also says it added "architectural safeguards" meant to cover whole classes of similar bugs, not just the individual cases.
What Tailscale SSH is
Tailscale builds a private mesh network, a "1," over 2, a VPN protocol. Ordinary SSH servers such as OpenSSH work over it unchanged. Tailscale SSH is a separate thing: an SSH server built into the Tailscale client. It authenticates users with their Tailscale identity rather than SSH keys, and it enforces the 3, the central set of access rules. Administrators can say who may connect to which machines and which local Linux/Unix accounts they may log in as. They can also require "4," an extra authentication step before a session starts. The server can record and audit sessions too.
The hard part: dropping privileges correctly
Every SSH server faces the same structural problem, and the post names it directly. The server needs elevated privileges, usually root, for jobs like starting a session as a different Unix user. Once the session exists, nothing the user does should inherit those privileges. That includes the shell, file transfers, and 5, which is SSH's ability to tunnel TCP ports or Unix sockets through the connection.
This is easy to get wrong because some of those operations are performed by the server process on the user's behalf. Here is a general illustration (not the specific Tailscale bug, which the post doesn't describe). Say a user logged in as alice asks to forward a local Unix socket. If the root daemon opens that socket itself, rather than doing it with alice's identity, alice can reach sockets only root should touch. Or she can bind ports an unprivileged user can't. Every code path that acts for the session needs the same restriction, and missing a single one breaks the boundary.
What was found
Tailscale says the SSH flaws were in exactly that area. They concerned how permissions were enforced after a connection had been authorized. The authentication and policy checks that decide who may connect were not at fault. Under certain conditions, an authenticated session could do things beyond the privileges of its configured local user, including through SSH forwarding. "In these cases we didn't enforce them correctly," the post says.
The company stresses the preconditions. An attacker needs:
an existing foothold on an authorized device in the tailnet;
SSH access to the target explicitly permitted in the policy file;
whatever conditions the vulnerable functionality requires.
Shaver also disputes the report's name. He says nothing here is self-replicating malware. It is better described as 6 confined to connections the policy file already allowed, and Tailscale's investigation found an attacker could reach only machines SSH policy already permitted. Put plainly: the flaws did not widen who could get in where. They widened what a legitimate session could do once inside, possibly up to more privilege than the account it logged in as. That is still serious, because it can turn a low-privilege login into higher local privilege on the target. The post doesn't say whether that went as far as root.
Serve, 7 and 8
The report also included five findings in Serve and Funnel. Serve shares a local service with the tailnet; Funnel exposes it to the public internet. Tailscale classes three as bugs, fixed in v1.104.4. It says the other two are intended behavior. Bypassing the Funnel attribute check (a policy flag that controls which nodes may use Funnel) requires local admin access. And TS_SERVE_ALLOW_ALL_INTERFACES is an opt-in setting whose purpose is to expose Serve beyond the tailnet.
A further finding hit Conn25, the next generation of app connectors, which route traffic to specific applications or domains through designated tailnet nodes. Conn25 has not been released. Tailscale says it already knew about this bug, which is one reason Conn25 is still unshipped. Today's stable app connectors are not affected.
Timeline
Fri Oct 23: concerns spread on social media; the teams begin investigating, with outside security specialists.
Sat Oct 24, morning: Tailscale receives the report; the researcher publishes it about two hours later.
Weekend into Mon: the teams reproduce the issues, widen the review beyond the reported symptoms, and test fixes, focusing on Unix privileges and forwarding.
Mon Oct 26: an investigation update with initial guidance.
Release: fixes ship in v1.104.4, along with four bulletins, TS-2026-014 through TS-2026-017.
Two hours of notice is far shorter than coordinated disclosure norms; 90 days is a common convention. The post states the gap without criticizing the researcher, and it doesn't say why the report went out so fast.
What to do
Update to v1.104.4 or later if you use Tailscale SSH. Tailscale also recommends cutting SSH policies back to the users and devices that actually need them, and turning on check mode for sensitive systems. Both limit how far a compromised peer can move, whatever bugs exist in the server.
What the post leaves open
The post doesn't explain how any of the bugs worked, which forwarding paths were affected, or what the new architectural safeguards are. Readers have to go to the four bulletins for specifics. It also doesn't say whether any exploitation was seen in the wild, or how far a session could escalate. The design lesson holds regardless: getting authorization right says nothing about whether privileges are confined afterwards. A daemon that does work on users' behalf has to put every such code path behind the same privilege boundary.
Remember
The flaws were in confining a session after login, not in deciding who may connect.
Exploitation required a compromised authorized device plus SSH access the policy already allowed.
Tight SSH policies and check mode limit damage even when the server itself has bugs.
Networks hand traffic to each other at shared facilities: exchange points and carrier buildings. Smaller countries often have only one or two of them. That cuts costs and latency, but it puts many providers' traffic behind a single building's power and cooling.
Image: Cloudflare
1, the company's public traffic-monitoring service, recorded 49 Internet disruptions in July–September 2026. Government-ordered shutdowns accounted for 19, and 18 of those were exam-day shutdowns in Iraq. Power outages caused 14 across 10 countries, and natural disasters caused five. Radar spots outages because Cloudflare carries more than 20% of web traffic: when requests from a country or network drop sharply below normal, it flags a disruption. Causes come from utilities, operators and news reports, not from the traffic data.
Power is the real dependency
Routers, cell towers and data centers all stop when the grid does. Cuba's unstable grid took the Internet down four times: July 6, July 14, August 3, and a three-day blackout on September 18–20. Traffic drops ranged from 18% to 59%. In Ukraine, a Sevastopol power outage on July 5 cut traffic by 98% for eight hours. Drone strikes on energy infrastructure on August 12 caused a ten-hour disruption with traffic down by up to 95%.
The clearest single-point-of-failure case was Honduras. On September 10, a power failure at one 2, a building where networks exchange traffic, hit at least 11 major providers and cut national HTTP traffic by 63% for about three hours. Two networks stayed up: a cross-border Guatemalan provider (AS14754) and the carrier Celtel (AS52262). AS numbers identify independently run networks. The report infers both lean on infrastructure outside Honduras. They sat in a different failure domain.
In Phoenix, a data-center cooling failure on August 13 caused a near-total traffic drop for Namecheap (AS22612), a hosting and domain provider.
Disasters
Guam took its second super typhoon in under three months. Despite an earlier emergency declaration, Typhoon Bavi left only about 25% of 3, the local power lines, online, and traffic took days to recover. A magnitude 7.4 earthquake in Colombia damaged fiber and disrupted one major provider for four and a half days. In Kumamoto, Japan, a magnitude 7.1 quake hit desktop traffic but left mobile traffic largely unaffected. Floods in Nepal caused a two-hour drop of up to 18%.
Deliberate cuts
Iraq's exam shutdowns ran on a fixed early-morning UTC schedule, mostly between late August and late September. Its communications minister has promised a digital exam-distribution system so the shutdowns are no longer needed. Ethiopia shut down Tigray for 10 days amid renewed conflict. Regional traffic fell to zero and national traffic fell by up to 30%. In Russia's Far East, the state carrier 4 reported deliberate 5 fiber damage during elections. Cloudflare notes the timing but doesn't claim a link.
Most outages were short. Fourteen recovered within an hour and 16 within three hours. The report catalogues what happened rather than explaining root causes.
Cloudflare's quarterly disruption report for July–September 2026 counts 49 Internet disruptions seen by 1, the company's public traffic-monitoring service. Government-ordered shutdowns made up 19 of them, and 18 of those were exam-day shutdowns in Iraq. Power outages caused 14, spread across 10 countries. Natural disasters caused five. The rest were failures inside individual networks. Author Lai Yi Ohlsen's main point is that resilience at the routing layer means little when power or a physical building fails underneath it.
How the data is gathered
Radar does not probe networks directly. Cloudflare carries more than 20% of web traffic, so it knows what normal HTTP request volume (ordinary web requests) looks like for each country, region and 2, meaning an independently operated network with its own number. A disruption shows up as a sharp drop below that baseline. The method has a limit: Radar measures how much demand went missing, and causes come from outside sources such as utilities, operators and news reports. The report says so in one case, noting that "Radar data alone cannot determine" why a cable was cut.
Power: the dependency underneath everything
Routers, mobile base stations, data centers and interconnection facilities all need electricity. Several incidents show what happens when it goes:
Cuba lost connectivity four times as its unstable grid failed: July 6, July 14, August 3, and a three-day blackout from September 18 to 20. Traffic fell by between 18% (July 14) and 59% (August 3), so the grid knocked the Internet over at least once a month.
Ukraine: a power outage in Sevastopol on July 5 caused an eight-hour blackout and a 98% drop in HTTP traffic. On August 12, drone strikes on energy infrastructure caused a ten-hour disruption with traffic down by up to 95%.
Smaller events hit Eswatini, Botswana, Tajikistan, Kenya, Saint Lucia, Georgia and Gabon. Eswatini's was planned 3, a deliberate rotating cut used to stretch a limited power supply, not a sudden failure.
Honduras: one building, a whole country
The most instructive case for a systems engineer is Honduras. On September 10, a power failure at a single 4, a building where networks exchange traffic, affected at least 11 major providers. For about three hours, HTTP traffic across the country fell by 63%.
The per-AS breakdown is the useful part. Two networks were unaffected: Telecomunicaciones de Guatemala (AS14754), a cross-border provider, and mobile carrier Celtel (AS52262). The report infers that their Honduran service probably depends more on infrastructure outside the country. In other words, they had a different failure domain. Here is an analogy: a service with eleven "independent" replicas all racked in one data hall is only as available as that hall's power feed. The two networks that stayed up were the replicas in another region.
A related warning came from Phoenix on August 13. A cooling-system failure at a data center there caused a near-total traffic drop from Namecheap (AS22612), a domain registrar and hosting provider. The report flags cooling as a dependency that is becoming more critical. It gives no detail on the facility or why the failure took the whole network down.
Natural disasters
Guam was hit by Super Typhoon Bavi less than three months after Super Typhoon Sinlaku, which last quarter took four days to recover from. Officials declared a state of emergency earlier this time. Winds still brought down key transmission lines, and at one point only about 25% of (the local lines that carry power from substations to customers) were online. Internet traffic again took several days to recover. Preparation did not stop a power-driven outage.
Shutdowns on purpose
Iraq's exam shutdowns follow a fixed timetable. The report says they ran in a 03:30–04:00 UTC window, but it also says each lasted 15–90 minutes. Those two figures don't reconcile, and the report doesn't explain the gap. Three took place July 1–8 and most of the rest between August 26 and September 28. Citing 6, a shutdown-tracking project, the report says Iraq's communications minister, Mustafa Sanad, has promised a digital exam-distribution system that would remove the need for shutdowns. Syria and Sudan, which have also cut the Internet for exams in recent years, showed no such shutdowns this quarter. The report attributes this to differences in exam calendars rather than a change in policy.
In Ethiopia, renewed conflict in Tigray came with a 10-day government shutdown that took the region's traffic to zero. Even confined to one region, it pulled national HTTP traffic down by up to 30%. It recalls the 2020–2022 civil war, when Tigray was cut off from telecoms, power, banking, fuel and aid in what the World Health Organization called a "de facto blockade."
In Russia's Far East, fiber damage on September 19, during nationwide elections, disrupted Chukotka, Magadan, Kamchatka and Sakhalin. 7, the state-controlled carrier, called it deliberate damage to its 8 (the long-haul fiber linking regions) and restored service over backup channels. Cloudflare notes the timing but does not claim a link to the elections.
Network-level failures and recovery times
Outages inside single networks hit One Communications in Guyana (a cable cut), MEO in Portugal (a reported "mass attack"), Digicel Haiti, TurkNet in Turkey and Fanap Telecom in Iran. The report gives no traffic figures for these.
On recovery, 14 disruptions returned to normal traffic within an hour and 16 within three hours. It isn't clear whether the second figure includes the first.
What's left open
This is a catalogue, not a root-cause analysis. It shows outcomes clearly through traffic drops and which ASes survived. Mechanisms rest on third-party statements, and there are no figures on backup power, generator runtime, or why particular facilities had no redundancy. The lesson that holds up is architectural: failure domains are defined by shared power, buildings and cooling, not by how many providers or links you have. The Honduras networks that routed through another country were the ones that stayed up.
Remember
Eleven Honduran providers shared one building's power; only the two routed through infrastructure abroad stayed online.
Even disaster preparation didn't stop Guam's outage: with power lines down, traffic took days to recover.
Radar measures missing traffic, not causes. Its attributions depend on statements from utilities, operators and governments.
The article relies on two proxies. One is the Stack Overflow Developer Survey, which asks developers what they use. The other is DB-Engines, a ranking built from web mentions, search interest, job ads and similar signals. Both measure attention and stated preference, not deployed workloads.
Image: PlanetScale
Simeon Griggs of PlanetScale, a hosted-database company that runs MySQL and now sells Postgres, works backward through Postgres's history to find when it became the default database for new applications. He never names one moment. What his essay shows is a chain of choices, some deliberate and some close to accidental.
Where it stands
In Stack Overflow's survey, Postgres passed MySQL in 2023 (45.6% to 41.1%) and gained 6.9 points in 2025, its largest jump. A tracker of 32,955 database picks made by LLM coding tools shows Postgres well ahead. Griggs notes that surveys measure stated preference, not deployments.
The milestones, newest first
2014: 1. MongoDB and other document databases offered schemaless JSON storage and easy horizontal scaling. Postgres 9.4 added JSONB, a binary JSON type that can be indexed, so queries on fields inside documents stay fast. MySQL got native JSON almost a year later. Griggs says JSONB kept users from leaving but didn't attract new ones.
2011: Heroku. The hosting platform launched Heroku Postgres as a standalone service. The team had no strong preference. One ops engineer said Postgres had a good record for keeping data safe, and that decided it. Developers came for Heroku's convenience. Heroku also funded work on 2 (per-query statistics), JSON support and the DATABASE_URL convention. AWS followed with 3 Postgres in 2013, the year Postgres rose 36% on 4, a popularity ranking.
2010: MySQL's ownership problem. Oracle's purchase of Sun put MySQL under the biggest proprietary database vendor. MySQL's creator forked it as 5. The same year, Postgres 9.0 added built-in replication. MySQL kept growing, though, and YouTube built 6, a system for sharding MySQL across many servers.
1994–96: the rescue. After Berkeley ended the POSTGRES project, two graduate students forked it as Postgres95. They swapped its 7 query language for SQL, cut the code by about 25% and made it 30–50% faster. Volunteers renamed it PostgreSQL and formed a core team. With no single owner and a permissive license, any cloud can host and extend it.
1986: extensibility. Postgres was designed from the start to support extensions, and today's extension ecosystem grew from that.
Caveats
Griggs admits MySQL earned its early lead. It handled the web's simple queries well and ran on Windows. Uber moved from Postgres to MySQL in 2016. Postgres still lacks mature 8. PlanetScale's preview platform, Neki, claims 118 million queries per second across 512 shards, but the article gives no methodology for that figure.
PlanetScale's Simeon Griggs asks why a database designed in the 1980s is now the default for new applications. His answer is a backward walk through the moments that made Postgres look inevitable. He never names a single turning point. What comes through instead is a chain of choices: a license and governance model that let anyone host Postgres, a near-death rescue, a rival's ownership troubles, a hosting platform's almost offhand pick, and a timely feature that kept developers from leaving.
Keep the source in mind. PlanetScale made its name running MySQL on 1 and now sells Postgres, and the essay includes several product mentions.
Where Postgres stands now
Griggs uses three signals for "default."
Stack Overflow's survey. In 2023 Postgres passed MySQL, 45.6% to 41.1% of all respondents. It has led every year since, and in 2025 it gained 6.9 points, its largest one-year jump.
Coding tools. A tracker of 32,955 database choices made by LLM coding tools shows Postgres well ahead. Hosted services are counted under the engine they run. The article doesn't give the exact share.
Money. In 2025, investors and cloud providers backed Postgres with acquisitions and infrastructure. The article doesn't name the deals.
Part of the 2025 surge came from extensions. 2, an extension that adds vector similarity search, let teams skip a separate vector database. Griggs treats 2025 as the payoff, not the cause. He also concedes that a survey lead shows popularity becoming visible, not becoming inevitable, and that surveys capture what people say, not what they deploy.
2013–14: surviving the document-database wave
In the early 2010s, MongoDB and other NoSQL systems threatened relational databases as a class. They offered schemaless JSON-like documents, no migrations, and horizontal scaling (spreading data across many machines). MongoDB replaced MySQL as the "M" in the MEAN/MERN JavaScript stacks.
Postgres 9.4 answered in December 2014 with 3, a binary JSON column type. The point of JSONB was indexing, not just storage. Postgres could index fields inside JSON documents, so a query filtering on a nested key could use an index instead of scanning every row. MySQL shipped a native JSON type almost a year later. The release notes argued that users "no longer have to choose between relational and non-relational data stores."
Griggs is careful about what JSONB achieved. It covered much of the document-database feature set without making Postgres a true competitor. It kept existing users from leaving but didn't bring in new ones. On 4, Postgres was first threatened by MongoDB, then overtook it, and the gap widened as MongoDB declined.
2011: Heroku's near-random choice
Griggs makes his strongest case for convenience. Before managed databases, "hosted database" usually meant a one-click MySQL install on a shared host's cPanel. Heroku, a platform-as-a-service, made provisioning a database trivial. It first offered Postgres in 2007 and launched Heroku Postgres as a standalone service in November 2011.
The engine choice was nearly arbitrary. Craig Kerstiens, quoted in the essay, recalls that most of the team had no opinion. One security and ops engineer said Postgres "has always had a good record of being safe and reliable for data," and that settled it. Developers then followed Heroku's convenience, not Postgres itself.
Heroku also put money into Postgres:
It funded improvements to 5, the extension that records per-query execution statistics.
It worked with core developers on JSON and JSONB.
It pushed the DATABASE_URL convention, which puts all connection details in one environment variable.
It later hired upstream contributors.
The demand drew competitors. AWS launched 6 Postgres, its managed service, in 2013. That same year Postgres had its largest one-year rise on DB-Engines, 36%. Heroku itself is now in "sustaining engineering" mode, but the developer expectation it created stuck.
2010: MySQL's ownership problem
Why not MySQL, which dominated the web? Griggs points to ownership. Sun bought MySQL in 2008, and Oracle, the largest proprietary database vendor, bought Sun in January 2010. On the day the deal was announced in 2009, MySQL's creator forked it as 7 because he didn't trust Oracle. When the European Commission approved the acquisition, it named Postgres as a viable alternative.
Griggs doesn't overstate this. MySQL kept growing for years. Postgres 9.0, released in late 2010, added built-in replication, one of the last practical reasons to prefer MySQL. In the same year YouTube built Vitess to shard MySQL past a single primary, a scale few Postgres deployments had tried. His conclusion is that 2010 made Postgres the most likely alternative to MySQL, not its replacement.
1994–96: the rescue
Postgres nearly died. Michael Stonebraker created POSTGRES at Berkeley, then left in 1992 to co-found Illustra, a commercial spin-off. The research project ended with version 4.2 in 1994. Two graduate students, Andrew Yu and Jolly Chen, needed a database for other work and forked it as Postgres95. They:
replaced POSTGRES's own query language, 8, with SQL;
cut the codebase by about 25%;
improved performance by 30–50%.
In 1996 Bruce Momjian found the project down to one part-time maintainer. He and Marc Fournier started issuing patches and releases and renamed it PostgreSQL. Their volunteer group became the core team.
Griggs argues this structure matters most for today's market. With a permissive license and no single owner, every cloud can host, fork and extend Postgres freely, something MySQL under Oracle cannot match.
1986: designed to be extended
The original design made Postgres extensible, and its large extension ecosystem is what makes "just use Postgres" credible. Griggs suggests some of the credit belongs to the Postgres 9, the network protocol clients use to talk to the server. Many very different systems speak it: providers that replace the storage layer, Postgres running in the browser, Rust rewrites. All of them still count as "Postgres."
Trade-offs and what's left
Griggs admits Postgres didn't "deserve" its status for much of this history. MySQL was built for the short, simple queries the early web needed, and it ran on Windows, where most developers worked. Document databases solved real performance problems. Uber famously moved from Postgres to MySQL in 2016.
The main gap he names is 10, splitting one database across many machines. Several vendors are working on it, while Vitess has sharded MySQL since 2010 at Slack and GitHub. PlanetScale's own attempt, Neki, a new Postgres sharding platform modeled on Vitess, entered preview in September 2026. The company says it has sustained 118 million queries per second across 512 shards. The article gives no workload, query mix or hardware, so treat the number as a vendor claim.
The essay leaves its question open. One defensible reading of its evidence: the 1996 governance and license made Postgres hostable by anyone, and Heroku's 2011 pick turned that into real habit. The other milestones kept the advantage alive.
Remember
Heroku's 2011 choice of Postgres was nearly arbitrary, decided by one engineer's remark about data safety.
With no single owner and a permissive license, any cloud can host and fork Postgres. MySQL under Oracle can't offer that.
JSONB kept Postgres users through the MongoDB era, but convenient hosting is what brought new users in.
Share using type hints often or always held near 86% from 2024 to 2026.1 / 4
The third annual Python Typing Survey drew 1,794 responses. Most came from experienced developers: 76.4% had used Python for at least five years. Meta's 1 team runs the survey with JetBrains, Microsoft and Astral, which all build Python type checkers, and it was promoted through checker project channels. That probably tilts the sample toward typing enthusiasts.
Adoption flat, checkers in flux
Use of type hints barely moved. 85.5% use them often or always, compared with 88.0% in 2024 and 85.9% in 2025. What changed is which static checker people use. 2, the original checker, is slow, and newer Rust-based checkers such as Pyrefly (Meta) and 3 (Astral) now compete with it and with Microsoft's 4. Speed was the most common reason for choosing a checker, at 56.5%. Half of respondents (49.9%) now run two or more checkers, up from 46.0% in 2025. Of 264 Pyrefly users, 83.3% also use another checker.
Teams split the work between them. One team runs Mypy as the authority in CI while each developer uses whatever checker their IDE provides. Another runs fast Pyrefly over everything, then runs the more thorough Pyright only on files Pyrefly fails. The cost is disagreement. 33.3% of all respondents, and 42.7% of multi-checker users, report inconsistencies between checkers.
Libraries are still the problem
Missing type information in third-party libraries was the top difficulty, at 65.1%, and 44.6% said the type system can't describe what their code does. Even libraries that ship 5 (type-only signature files) fall short when frameworks create behavior at runtime. Respondents repeatedly named Django, SQLAlchemy, Pydantic, NumPy, pandas and Polars. Meta is working with 6 on pandas and NumPy typing.
Who struggles depends on how often they use types. 41.6% of occasional users found typing too complex, against 14.5% of frequent users. Frequent users were far more bothered by library gaps (70.0% vs 36.2%). The most wanted feature is better Callable syntax (45.7%), because Callable[[int, str], bool] is clumsy.
Editors and help
82.9% run a checker in their editor. From 2024 to 2026, Stack Overflow use for typing help fell from 46.4% to 22.9%, while typing docs rose to 65.9% and LLM chat to 41.7%. The authors want error messages to link to short explanations. Many respondents now let AI tools write type hints, though some complain that these tools silence errors with # type: ignore.
The 2026 Python Typing Survey drew 1,794 responses, mostly from experienced developers: 76.4% had used Python for at least five years. This is the survey's third year. Meta's 1 team runs it with JetBrains (PyCharm), Microsoft's Python team, Astral's 2 team and community contributors. The headline result is a contrast. How often people use type hints barely moved, but which checker they use changed sharply. Meanwhile the oldest complaint, untyped or badly typed third-party libraries, is still the biggest one.
One caveat applies to every number below. The survey was shared through checker project websites and social accounts, typing forums, Reddit and similar channels, and the people who build the checkers co-organized it. Respondents probably lean toward typing enthusiasts. The authors note that a different group answered each year, so year-over-year comparisons describe changing samples, not the same people tracked over time.
Adoption is flat; checker choice is not
The share of respondents who use type hints often or always held between 85.5% and 88.0%: 88.0% in 2024, 85.9% in 2025, 85.5% in 2026.
Checker choice moved far more. The article quotes a 2024 response that predicted the shift: "A faster 3. Its lack of speed led to ecosystem fracturing and other type checkers don't support Mypy plugins and behave differently in general." By 2026, several newer open-source checkers were available. Speed or performance was the most common reason for choosing one, at 56.5%. Measured against the same list of checkers in both years, 49.9% of respondents used two or more in 2026, up from 46.0% in 2025.
The detailed numbers show how teams split the work. Of 700 Mypy users, 297 also used Mypy's editor plugin, and 314 used a different named checker in the editor without Mypy's plugin. Of 264 Pyrefly users, 220 (83.3%) also used another checker. One respondent's team uses whatever checker each person's IDE provides, with Mypy as the authority in CI. Another runs Pyrefly across the codebase in CI, then runs 4 only on files where Pyrefly fails. Pyright handles the team's unusual typing patterns, and Pyrefly keeps the full pass fast. It works like a two-stage filter: a fast pass first, then a slower, more thorough pass only where needed.
Running several checkers has a cost. Overall, 33.3% of 1,486 respondents reported inconsistencies between checkers. Among the 738 who used multiple checkers, the figure was 42.7%. The authors suggest that checker projects document their intentional differences, so teams can tell a deliberate design choice from a bug.
Libraries remain the main pain point
Missing type information in third-party libraries was the top difficulty, chosen by 65.1% of 1,486 respondents. Another 44.6% said the type system cannot describe everything their code does. Shipping 5 doesn't fix this on its own. Of 156 free-text answers, 22 described dynamic constructs: decorators, metaprogramming, or framework behavior. Ten described arrays, dataframes or scientific typing, and at least eight described annotations that were wrong, incomplete or too broad. Respondents kept naming Django, SQLAlchemy, Pydantic, NumPy, pandas and Polars. One wrote: "Django does so much black magic it's a wonder a type checker works at all."
The trouble is that these libraries build behavior at runtime, such as model fields turned into attributes, query objects created by metaclasses, or dataframe columns known only from the data. Static annotations can't easily express that. The authors suggest two directions: new typing features, and checker support written for specific libraries and frameworks (Mypy plugins already do this, which is part of why switching away from Mypy is hard). The Pyrefly team is also working with 6, a consultancy that maintains much of the scientific Python stack, on pandas-stubs and NumPy typing.
Who finds typing hard depends on how often they use it
Problems differ sharply by how often people use type hints. Among those who use them rarely or sometimes, 41.6% found the type system too complex or verbose, against 14.5% of frequent users. Missing library typing goes the other way: it bothered 36.2% of occasional users and 70.0% of frequent ones. A plausible reading, though the article doesn't prove it, is that frequent users have absorbed the complexity and now hit the edges of what's typed.
Years of typing experience barely mattered. Complexity complaints were 18.2% for zero to two years, 16.0% for three to six, and 21.0% for seven or more. Newcomers to typing aren't Python beginners: of 396 respondents with up to two years of typing experience, 77.3% used hints often or always, and 87.1% had at least three years of Python. The authors conclude that typing guides should assume Python fluency and show how to add types to an existing repository. Tools should give a useful first run with little configuration and clear error messages.
The most requested missing feature was better Callable syntax, chosen by 45.7%. Today, a function that takes an int and a string and returns a bool is written Callable[[int, str], bool], which is awkward and can't express keyword arguments directly. (A proposal for arrow-style syntax, 7, was rejected in 2021.) Demand was similar whether or not respondents complained about complexity.
Editors, help sources, and AI
Readability and documentation were the top reasons to use type hints (93.6%). Of those who rated editor support, 84.8% gave it a 4 or 5. Real-time feedback is the norm: 82.9% run a checker in their editor, and 59.3% use VS Code. Where people look for help has changed. From 2024 to 2026, Stack Overflow use fell from 46.4% to 22.9%, LLM chat rose from 26.0% to 41.7%, Python typing docs rose from 56.2% to 65.9%, and checker-specific docs reached 60.5%. The authors want error messages to link to short explanations with examples.
The survey also asked about AI coding tools. 42.5% of respondents had AI write type hints, and 24.4% had an AI tool run their checker. Some complained that agents use object for everything or scatter # type: ignore comments to silence errors. The share who weren't sure types help AI-assisted coding was 29.8%, and the authors say that needs empirical study.
What's open
The article reports percentages without confidence intervals. It doesn't break down checker share in the text beyond what the chart shows, and it doesn't quantify how often checker disagreements cause real bugs. The full results and raw data are available for download.
Remember
Speed drove checker churn: 56.5% chose a checker mainly for performance, and many pair a fast checker with a thorough one.
Running several checkers has a cost: 42.7% of multi-checker users hit inconsistencies between tools.
Dynamic frameworks like Django and pandas defeat static typing even with stubs; that, not syntax, is the main pain.
Japan: a magnitude 7.1 earthquake led to evacuation orders for about 150,000 people in Kumamoto. Desktop traffic fell, but mobile traffic stayed largely unaffected. That pattern fits fixed-line or building-level power loss while cellular networks kept running, though the report doesn't explain the split.
Colombia: a magnitude 7.4 earthquake in August damaged fiber-optic infrastructure. Traffic from Colombia Telecomunicaciones (AS3816) dropped significantly for four and a half days.
Nepal: flash floods on August 26 along the Bhote Koshi and Trishuli rivers knocked out power. The result was a two-hour regional disruption with traffic down by up to 18%.