3941 stories
·
3 followers

Browser De-Slop

1 Share

Modern browsers ship with an insane amount of bloatware.

You can point and click in the browser settings to disable most of it. Or, you can de-slop the browser by force using a policy file.

To get started, create a JSON file at the appropriate path for your distribution. Here’s a few that I’m aware of:

Allegedly, these policies are also supported on Windows via Group Policy and MacOS using plist files. I wouldn’t know, since I use a real operating system.

You should read the docs for each option to understand what it does. My configuration here does a few things:

{
  "policies": {
    "ExtensionSettings": {
      "uBlock0@raymondhill.net": {
        "install_url": "https://addons.mozilla.org/firefox/downloads/latest/ublock-origin/latest.xpi",
        "installation_mode": "force_installed"
      }
    },
    "3rdparty": {
      "Extensions": {
        "uBlock0@raymondhill.net": {
          "toOverwrite": {
            "filterLists": [
              "user-filters",
              "ublock-filters",
              "ublock-badware",
              "ublock-privacy",
              "ublock-quick-fixes",
              "ublock-unbreak",
              "easylist",
              "easyprivacy",
              "adguard-spyware-url",
              "urlhaus-1",
              "plowe-0",
              "fanboy-cookiemonster",
              "ublock-cookies-easylist",
              "fanboy-thirdparty_social",
              "ublock-annoyances"
            ]
          },
          "toAdd": {
            "trustedSiteDirectives": [
              "intranet.example.com"
            ]
          }
        }
      }
    },
    "UserMessaging": {
      "WhatsNew": false,
      "ExtensionRecommendations": false,
      "UrlbarInterventions": false,
      "SkipOnboarding": true
    },
    "OverridePostUpdatePage": "",
    "OverrideFirstRunPage": "",
    "EnableTrackingProtection": {
      "Value": false,
      "Cryptomining": false,
      "Fingerprinting": false,
      "Locked": false
    },
    "Cookies": {
      "Behavior": "reject-tracker-and-partition-foreign",
      "BehaviorPrivateBrowsing": "reject-tracker-and-partition-foreign"
    },
    "NoDefaultBookmarks": true,
    "DisablePocket": true,
    "DisableAppUpdate": true,
    "CaptivePortal": false,
    "Certificates": {
      "Install": [
        "/usr/local/share/certs/trusted/your-custom-root-ca.crt"
      ]
    },
    "DisableFeedbackCommands": true,
    "DisableFirefoxAccounts": true,
    "DisableFirefoxStudies": true,
    "DisableTelemetry": true,
    "DontCheckDefaultBrowser": true,
    "OfferToSaveLoginsDefault": false,
    "DNSOverHTTPS": {
      "Enabled": false
    },
    "SearchSuggestEnabled": false,
    "Homepage": {
      "URL": "about:home",
      "StartPage": "homepage"
    },
    "SearchEngines": {
      "Add": [
        {
          "Name": "ddg",
          "URLTemplate": "https://duckduckgo.com/?q={searchTerms}",
          "Method": "GET",
          "IconURL": "https://duckduckgo.com/favicon.ico",
          "Alias": "ddg",
          "Description": "DuckDuckGo",
          "SuggestURLTemplate": "https://duckduckgo.com/ac/?q={searchTerms}&type=list"
        }
      ],
      "Default": "ddg"
    },
    "FirefoxHome": {
      "Search": true,
      "TopSites": false,
      "SponsoredTopSites": false,
      "Highlights": false,
      "Pocket": false,
      "SponsoredPocket": false,
      "Snippets": false
    },
    "AIControls": {
      "Default": {
        "Value": "blocked",
        "Locked": true
      }
    },
    "ExtensionUpdate": true,
    "Preferences": {
      "dom.security.https_only_mode": {
        "Value": true,
        "Status": "locked"
      },
      "dom.push.connection.enabled": {
        "Value": false,
        "Status": "default"
      },
      "browser.urlbar.suggest.quicksuggest.nonsponsored": {
        "Value": false,
        "Status": "locked"
      },
      "browser.urlbar.suggest.quicksuggest.sponsored": {
        "Value": false,
        "Status": "locked"
      },
      "browser.toolbars.bookmarks.visibility": {
        "Value": "newtab",
        "Status": "default"
      },
      "browser.safebrowsing.malware.enabled": {
        "Value": false,
        "Status": "locked"
      },
      "browser.safebrowsing.phishing.enabled": {
        "Value": false,
        "Status": "locked"
      },
      "browser.safebrowsing.downloads.enabled": {
        "Value": false,
        "Status": "locked"
      },
      "browser.newtabpage.activity-stream.feeds.section.topstories": {
        "Value": false,
        "Status": "locked"
      },
      "browser.newtabpage.activity-stream.showSponsoredCheckboxes": {
        "Value": false,
        "Status": "locked"
      },
      "browser.newtabpage.activity-stream.widgets.system.weather.enabled": {
        "Value": false,
        "Status": "default"
      },
      "browser.urlbar.suggest.quicksuggest.all": {
        "Value": false,
        "Status": "locked"
      },
      "browser.tabs.groups.smart.userEnabled": {
        "Value": false,
        "Status": "default"
      },
      "signon.management.page.breach-alerts.enabled": {
        "Value": false,
        "Status": "locked"
      },
      "privacy.fingerprintingProtection.pbmode": {
        "Value": false,
        "Status": "default"
      },
      "signon.firefoxRelay.feature": {
        "Value": "disabled",
        "Status": "locked"
      }
    }
  }
}

You should read the docs for these settings to make sure they’re right for you. My configuration here does a few things:

Unfortunately, Chrome does not support adding custom certificate authorities via the policy file anymore (I resorted to some hacky automation that adds the certificate to the user’s ~/.pki/nssdb on first login).

{
  "AdvancedProtectionAllowed": false,
  "AlternateErrorPagesEnabled": false,
  "AutofillCreditCardEnabled": false,
  "BackgroundModeEnabled": false,
  "BlockThirdPartyCookies": true,
  "BrowserGuestModeEnabled": false,
  "BrowserLabsEnabled": false,
  "BrowserNetworkTimeQueriesEnabled": false,
  "BrowserSignin": 0,
  "CloudPrintProxyEnabled": false,
  "CloudReportingEnabled": false,
  "DefaultBrowserSettingEnabled": false,
  "DefaultCookiesSetting": 1,
  "DnsOverHttpsMode": "off",
  "EnableAuthNegotiatePort": true,
  "EnableMediaRouter": false,
  "MetricsReportingEnabled": false,
  "NetworkPredictionOptions": 2,
  "PasswordManagerEnabled": false,
  "PaymentMethodQueryEnabled": false,
  "PrivacySandboxAdMeasurementEnabled": false,
  "PrivacySandboxAdTopicsEnabled": false,
  "PrivacySandboxPromptEnabled": false,
  "PrivacySandboxSiteEnabledAdsEnabled": false,
  "PromotionalTabsEnabled": false,
  "SafeBrowsingProtectionLevel": 0,
  "SearchSuggestEnabled": false,
  "SyncDisabled": true,
  "TranslateEnabled": false,
  "UrlKeyedAnonymizedDataCollectionEnabled": false,
  "DefaultSearchProviderEnabled": true,
  "DefaultSearchProviderName": "DuckDuckGo",
  "DefaultSearchProviderImageURL": "https://duckduckgo.com/favicon.ico",
  "DefaultSearchProviderEncodings": ["UTF-8"],
  "DefaultSearchProviderSearchURL": "https://duckduckgo.com/?q={searchTerms}",
  "DefaultSearchProviderSuggestURL": "https://duckduckgo.com/ac/?q={searchTerms}&type=list",
  "DefaultSearchProviderNewTabURL": "https://duckduckgo.com/chrome_newtab",
  "ExtensionSettings": {
    "ddkjiahejlhfcafbddmgiahcphecmpfh": {
      "installation_mode": "force_installed",
      "update_url": "https://clients2.google.com/service/update2/crx"
    }
  },
  "3rdparty": {
    "extensions": {
      "ddkjiahejlhfcafbddmgiahcphecmpfh": {
        "disableFirstRunPage": true,
        "defaultFiltering": "complete",
        "noFiltering": [
          "intranet.example.com"
        ],
        "rulesets": [
          "+default",
          "+annoyances-cookies",
          "+annoyances-notifications",
          "+annoyances-others",
          "+annoyances-overlays",
          "+annoyances-social",
          "+annoyances-widgets",
          "+adguard-spyware-url"
        ]
      }
    }
  }
}
Read the whole story
emrox
10 hours ago
reply
Hamburg, Germany
Share this story
Delete

AliExpress webpage keeping multipoint Bluetooth headphones active with WebAudio fingerprinting

1 Share

Recently I ran into a strange problem with my Bluetooth headphones. They support multipoint Bluetooth audio, so they can be connected to my PC and phone at the same time. Normally the PC takes priority playing audio, with my phone being able to play audio when nothing is playing on the PC.

Usually I listen to music on my phone but with notifications or youtrube playing through the PC, this works reliably until I open an AliExpress page in Firefox or Chrome (other browsers untested).

Shortly after loading the AliExpress homepage, audio from my phone would stop playing. Closing the AliExpress tab fixes it immediately. Muting the tab/firefox/Windows does not help, and there is no visible video, music, or other media playing on the page. 

This seemed suspicious enough to investigate.

Looking for hidden media

My first thought was an autoplaying product video or advertisement, so I checked for the usual suspects:

  • <audio> and <video> elements
  • calls to HTMLMediaElement.play()
  • active Media Session metadata
  • media requests
  • embedded frames containing media

None of these showed anything useful. There were no audio or video elements, no media playback calls, and navigator.mediaSession.playbackState remained none.

A clue was that the problem did not begin immediately. It appeared after the page had been sitting idle for several seconds. I instrumented the page before loading it and watched the Web Audio API instead of only looking for conventional media elements.

The basic idea was to wrap the AudioContext constructor and record whenever a page created an audio-processing context:

const OriginalAudioContext = window.AudioContext;

window.AudioContext = class extends OriginalAudioContext {

constructor(...args) {

        super(...args);

        console.log("AudioContext created", {

            state: this.state,

            stack: new Error().stack

        });

    }

};

I also wrapped AudioNode.prototype.connect() so I could see whether anything was connected to the context's audio destination.

That finally found it, two hidden audio contexts!

During an idle capture of the AliExpress homepage, the page created two AudioContext objects. Both entered the running state and both connected nodes to AudioContext.destination.

At the same time there were still:

  • zero <audio> or <video> elements
  • zero media play() calls
  • no active Media Session
  • no audible sound

The constructor stack traces pointed to two scripts:

<a href="https://assets.aliexpress-media.com/g/AWSC/uab/1.140.0/collina.js" rel="nofollow">https://assets.aliexpress-media.com/g/AWSC/uab/1.140.0/collina.js</a>

<a href="https://assets.aliexpress-media.com/g/AWSC/fireyejs/1.231.67/fireyejs.js" rel="nofollow">https://assets.aliexpress-media.com/g/AWSC/fireyejs/1.231.67/fireyejs.js</a>

The first context was created by collina.js, while the second came from fireyejs.js. Both sit under an AWSC directory and appear to be part of Alibaba's browser security and anti-abuse tooling.

The scripts are extremely obfuscated, but enough names and operations survive for AI to work out what the audio code is doing.

What the audio code does

Both scripts build a WebAudio graph resembling this:

Sawtooth oscillator

    -> AnalyserNode

    -> ScriptProcessorNode

    -> GainNode set to zero

    -> AudioContext.destination

The oscillator generates a known waveform. The analyser measures the result after it has passed through the browser's audio implementation, and the script reads frequency data from it.

The gain is set to zero, so the user should not hear anything. However, the graph is still connected to the system audio destination. Connecting it to the destination causes the browser to actively process the graph, even though the final volume is zero.

This is very different from an autoplaying video. There is no media element for the browser's normal tab mute control to stop. As far as the page is concerned, it is performing live audio processing.

In my case, that appears to have been enough for Firefox or Windows to keep the Bluetooth audio path active, preventing my multipoint headphones from switching cleanly back to the phone.

This looks like fingerprinting

The WebAudio test is not the only measurement in these scripts. Inspection of the bundles found code that queries or measures:

  • canvas rendering and toDataURL()
  • WebGL renderer information, extensions, and shader precision
  • audio oscillator and analyser output
  • screen and viewport dimensions
  • device pixel ratio
  • hardware concurrency and device memory
  • installed browser plugins
  • supported audio and video formats
  • WebRTC behaviour
  • browser performance timing
  • mouse, touch, focus, and scroll events
  • device motion and orientation
  • properties commonly associated with browser automation

There is also code for serialising and encrypting results, making requests to Alibaba telemetry services, and sending data with fetch() or sendBeacon().

This is a fairly comprehensive browser and device fingerprint.

Audio fingerprinting works because small differences in browser versions, operating systems, audio libraries, and hardware can produce slightly different results from the same generated signal. It is not necessarily enough to uniquely identify a device by itself, but it becomes much more useful when combined with canvas, WebGL, hardware, timing, and interaction data.

I cannot see what AliExpress does with the resulting data after it reaches their servers. It may be used as a persistent device identifier, but it could also be one input into a fraud or bot-detection score. 

Why AliExpress would want this

AliExpress has plenty of reasons to distinguish normal shoppers from automated or suspicious clients as well as tracking users browsing habits. The site has to deal with account takeovers, fake accounts, scraping, automated purchasing, payment fraud, review manipulation, and abuse of coupons or new-customer promotions. They also like most large businesses make use of large datasets of user behaviour to better market products and services.

Cookies are not especially reliable for this purpose because they can be cleared, copied, or replaced. A fingerprint made from many independent browser measurements is harder to manipulate consistently.

Interaction data can also help determine whether a browser is controlled by a person or automation. From AliExpress's perspective, this could reduce fraud and allow trusted customers through without showing a CAPTCHA every few pages. (Not that Aliexpress shies away from their AI generated CAPTCHAs)

Personally I do not want a shopping homepage silently exercising my graphics, audio, WebRTC, hardware, and motion APIs, etc, to track my behaviours, especially if it has such an annoying effect as blocking my music. Perhaps if AliExpress wasn't blocking my music I never would've looked into what the site was doing.

Blocking it with uBlock Origin

I tested blocking the two identified script families. With both requests blocked, the AliExpress homepage continued to render and no AudioContext objects or destination connections appeared during the control capture.

In Firefox, I use the official uBlock Origin extension by Raymond Hill. To block the scripts open the uBlock dashboard, select My filters, and add:

! AliExpress AWSC fingerprinting scripts

||assets.aliexpress-media.com/g/AWSC/uab/*/collina.js$script,domain=aliexpress.com

||assets.aliexpress-media.com/g/AWSC/fireyejs/*/fireyejs.js$script,domain=aliexpress.com

Click Apply changes, close any existing AliExpress tabs, and open the site again. Existing tabs need to be closed because blocking a script does not shut down an audio context that it has already created.

These rules are deliberately narrow. They block only the two observed script families and only when requested by AliExpress. I would not be surprised if this stops working in the future, I'll cross that bridge when it comes to it.

Because these scripts appear to be connected with anti-fraud systems, blocking them may cause extra CAPTCHAs or problems during login or checkout. So far the homepage and ordinary product browsing still work, but I would temporarily disable the rules if AliExpress refuses a legitimate login or payment.

Why I am blocking it

The anti-fraud use case is understandable, but this implementation has several problems.

It runs on the general shopping homepage before I perform a sensitive action. It collects a broad set of device and behavioural measurements, the implementation is deliberately difficult to inspect, and there is no visible indication that the page has started a live audio-processing graph.

It also produced a very real hardware side effect. A silent fingerprinting test was able to interfere with Bluetooth multipoint switching, while the browser's mute control did nothing.

If a hidden analytics or security feature can take ownership of an audio path strongly enough to change how external hardware behaves, blocking it seems like a reasonable trade-off.

I also cannot prove how long AliExpress stores the fingerprint or whether it is used across other Alibaba properties. The client code proves that extensive fingerprint-like measurements are collected and transmitted, but server-side retention and identity linkage are not visible from the browser. Can you really trust anyone to have your best interests at heart?

TL;DR

The AliExpress homepage silently creates two running WebAudio graphs from heavily obfuscated Alibaba security scripts. The graphs generate and analyse a waveform as part of a much larger browser fingerprint, then connect through a zero-gain node to the system audio destination preventing the user from hearing anything.

On my setup, this appears to keep the PC's Bluetooth audio path active and prevents multipoint headphones from switching back to a phone. Muting the tab does not fix it because there is no conventional media element to mute.

Blocking collina.js and fireyejs.js with the two uBlock Origin rules above prevented the hidden audio contexts from being created and means I can happily listen to my music without being interrupted while browsing Aliexpress.

Read the whole story
emrox
10 hours ago
reply
Hamburg, Germany
Share this story
Delete

The Future of CSS: Target Multiple Classes with the Class Prefix Selector

1 Share

To target multiple classes that share the same prefix, you’d typically have to resort to brittle attribute selectors or add extra base classes to your markup. To make things easier, CSS is getting a new selector: The Class Prefix Selector (.prefix-*).

~

⚠️ This post is about an upcoming CSS feature. You can’t use it … yet.

This feature is hot off the press — it was resolved on only two weeks ago — and currently only exists in spec text. The spec will most likely see some changes before this is ready for a browser to implement.

~

The Problem: Targeting Multiple Prefixed Classes

When coming up with classnames for use in the class attribute, a common practice is to use a prefix to retain some grouping or hierarchy. You might be familiar with classes like .btn-primary, .btn-secondary, .btn-danger, and so on.

To apply a base style to all of these buttons today, you typically have to list them all out, or introduce a separate .btn base class:

/* Adding a base class */
.btn {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

/* Or listing everything... yuck! */
.btn-primary,
.btn-secondary,
.btn-danger {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

Some of you even resort to substring-matching attribute selectors, but those can be notoriously brittle and ugly when dealing with multiple classes on a single element:

/* Works, but can be error-prone with whitespace */
[class^="btn-"],
[class*=" btn-"] {
  padding: 0.5rem 1rem;
}

~

The Solution: The Class Prefix Selector

Just two weeks ago, at the CSS Working Group F2F meeting in Berlin (August 2026), we resolved to add a dedicated Class Prefix Selector to the CSS Selectors Level 5 specification. The idea was originally pitched by Lea Verou back in 2024 (w3c/csswg-drafts/#10001).

The syntax is incredibly straightforward:

.btn-* {
  padding: 0.5rem 1rem;
  border-radius: 4px;
}

That’s it! The -* part at the end makes the selector a Class Prefix Selector and will try to match any class that begins with that hyphen-separated prefix.

It’s a huge win for utility classes and design systems, allowing you to easily target groups of related elements without having to bloat your HTML payload or write fragile attribute selectors.

~

What about the empty string?

An interesting question that popped up during the discussions is whether .foo-* should match the empty string (w3c/csswg-drafts/#14291), meaning: should .foo-* also match an element that merely has the .foo- class?

While the exact default behavior is still being ironed out, currently the selector is specified to only match classes that start with the prefix and that have at least one character beyond the prefix (and the first such character beyond the prefix is not also a hyphen)

So no, class="foo-" would NOT be matched by .foo-*, which I think is fine. That same selector also would not match class="foo--", which is also probably fine.

~

What about non-dashes?

The Class Prefix Selector is currently limited to hyphen-separated prefixes, at least at first. Other separators, like _, might be added as possibilities in the future as we receive request from authors like yourself about what would be needed.

One thing that is already quite clear right now, is that there must at least be some separator. Arbitrary prefixes (like .foo*) are not going to be allowed for at least two reasons:

  1. You could accidentally overselect: .foo* would also match .footer
  2. Selector Performance: Browsers typically create buckets for class selectors for quick selector matching. Adding arbitrary wildcards defeat that optimization.

Similarly, wildcards in the middle of a selector (such as .card-*-primary) are also not going to be allowed.


# Browser Support

💡 Although this post was originally published in August 2026, the list below is constantly being updated. Last update: August 20, 2026.

Since this was literally just resolved at the CSSWG F2F in Berlin two weeks ago, browser support is currently non-existent. To follow along with the progress – if any – you can follow these browser issues:

Chromium (Blink)

❌ No Support

Subscribe to CrBug #543356377 to follow along.

Firefox (Gecko)

❌ No Support

There is no bug tracking this yet.

Safari (WebKit)

❌ No Support

There is no bug tracking this yet.

This feature is still in its early days and needs to be fleshed out further, so could be that it takes a few more years before you can use it in production …


# Feature Detection

You can feature detect support with a regular @supports rule:

@supports selector(.foo-*) {
  /* Browser has support */
}

The following CodePen uses this and will light green when you browser supports it:

See the Pen
CSS Class Prefix Selector Support test
by Bramus (@bramus)
on CodePen.


Spread the word

Feel free to reshare one of the following posts on social media to help spread the word:

~

🔥 Like what you see? Want to stay in the loop? Here's how:

I can also be found on 𝕏 Twitter and 🐘 Mastodon but only post there sporadically.

Read the whole story
emrox
1 day ago
reply
Hamburg, Germany
Share this story
Delete

The Future of CSS: Target Multiple Classes with the Class Prefix Selector

1 Share
.btn-* { padding: 0.5rem 1rem; border-radius: 4px; }
Read the whole story
emrox
1 day ago
reply
Hamburg, Germany
Share this story
Delete

Bun 1.4 Rust rewrite is not looking good

1 Share

I care about Bun. I have been rooting for it since the initial release in 2022. I switched all my development from Node to Bun. I used it in the development of the Nue framework and now with my new project Hertta.

The last three months have not looked good for Bun. It started as one of the most impressive individual engineering projects I have seen, but has now turned into this weird AI-powered creature with continuous false promises and an increasingly frustrated community.

In the next version of Bun

In the next version of Bun used to be a positive tweet to watch for. For years it meant a feature had been implemented, tested, and would ship in a few days. This changed after the Rust rewrite. Now the posts are false promises about the upcoming release:

It’s now three months and counting since the last stable release, the longest gap in Bun’s history since 2022. Nothing unusual there. Software slips, that’s normal. It’s just that an account which used to communicate with real dates and real numbers has switched to vibing. And the user reaction is what you’d expect after constant false promises:

@jarredsumner okay I’m editing blog post it’s mostly done if I say a date you won’t believe me but let’s say tomorrow

We totally believe in you, Jarred

Rejoice fellas, tomorrow in Jarred Standard Time zone means we have a new blog coming next week.

You won’t care, but personally I am switching to go now. It’s not even funny, you are just stringing your users along again and again.

How can we believe you? You always make promises that you can’t keep, tomorrow, next week, Monday...

If you need 2 months to release it you can just say that instead of saying you’ll ‘release it tomorrow’ every week

Bun on GitHub

The Bun 1.4 rewrite is a big bet on AI. In the past month, 15.8k commits came from robobun, 1.6k commits from autofix-ci[bot], and 790 commits from Jarred.

6 months ago, most of Bun’s PRs came from people prompting Claude. Nowadays, most of Bun’s PRs come from Claude prompting Claude.

The project has over 5k open pull requests, which is the largest number of pull requests I’ve seen. For comparison, OpenClaw has 2.2k, and React has 441. GitHub recommends staying under 1,000 open PRs against a single branch before mergeability checks start timing out.

The biggest worry is, of course, the code itself. In the early days Jarred’s work was inspirational. I thought he was a true Zig talent, until I read Zig creator Andrew Kelley’s thoughts on the Bun rewrite:

We became increasingly horrified at the programming practices we saw in Bun’s codebase. Hacks on top of hacks. Abuse of assertions. Jarred was already writing slop well before he had access to LLMs.

What was the problem with Zig?

This rewrite is the most closely watched real-world test of whether AI agents can take over a production codebase with a human mostly directing rather than reading. Anthropic’s own reputation is also on the line: if this goes well, it is real proof of what agentic coding can do. If it goes badly, it will send a signal in the opposite direction.

The number of unsafe blocks in the Rust code suggests the rewrite did not deliver the memory safety that was given as the reason for doing the rewrite in the first place. Instead this rewrite feels more like an Anthropic ad.

And was Zig really the problem? Bun’s early identity was built on Zig: its performance, its fast compile times, its low friction, its direct memory control with a small team.

It feels like Jarred and Anthropic decided early on that this was going to be written in Rust, and used Zig’s memory issues as the excuse to let the world know how powerful Claude is. A rewrite like this would make great headlines, and it certainly did. Now we’re looking at the long tail of issues from the rewrite they didn’t prepare for.

Maybe Bun should have put that same AI-assisted effort into disciplined, human-understood Zig instead of a full language change. I never saw Jarred seriously engage with this option.

And ‘tomorrow’ has come and gone. Still no v1.4.

¯\_(ツ)_/¯

Read the whole story
emrox
2 days ago
reply
Hamburg, Germany
Share this story
Delete

Total eclipse of the Internet: traffic impacts in Iceland, Spain, and Portugal

1 Share

At a time when looking down at our devices is a ritual in daily life, a natural phenomenon that demands our attention communally upward is a welcome event. On Wednesday, August 12, a total solar eclipse swept from the North Atlantic across Europe, moving over Iceland and northern Spain and Portugal, with a deep partial eclipse over the rest of Western Europe, all near local sunset. This was the first total solar eclipse to cross mainland Europe in twenty years, and it drew millions outdoors to witness the moon pass between Earth and the sun. 

As we saw during the 2026 World Cup and the last total eclipse in 2024, online behavior is noticeably affected when an event at this scale takes place. In this blog post, we’ll use data from Cloudflare Radar to examine how Internet traffic shifted alongside the moon and the sun.  

Internet traffic dips align precisely with maximum obscuration

In the figure above, we measured HTTP request volume in five-minute buckets across the affected countries on eclipse day, and compared it to a normal-day baseline. Each row is a country (except for Alaska) and each column is a five-minute slice of August 12, 2025, the day of the eclipse. The countries appear above in the order in which they saw the eclipse.

The black diamonds mark the moment of maximum eclipse and the color shows the percent change in HTTP traffic versus the baseline (red = below normal, blue = above). We can see very clearly that the black diamonds overlay the darkest red, almost perfectly, signaling that as the eclipse deepened, Internet traffic decreased. The decrease was most significant along the path of totality and in countries that saw the deepest partial eclipse (Iceland, Ireland, the UK, France, Spain and Portugal) and all but absent where the sun was barely obscured (Sweden, Denmark, Poland, Switzerland). 

Where the eclipse was deep, the red color and black diamonds mirror each other: traffic falls into a trough that sits directly beneath the peak of obscuration and rebounds as the sun reappears, typically within minutes of maximum coverage as people return to their screens.


The scatter plot above suggests that these decreases are not due to random chance. Each point represents the peak solar obscuration of an individual country (x-axis), against the region's traffic dip (y-axis). The traffic dip is measured as the average percentage change versus baseline in the 15-minute window surrounding maximum eclipse. The downward trend of the dotted line following the dots demonstrates that regions along the path of totality saw traffic fall by roughly 15% to 30%, whereas areas experiencing only a shallow partial eclipse dipped far less or not at all. While local variables like population density, time of day, and cloud cover account for scatter at any given coverage level, the overall direction remains consistent. Paired with the precise timing of the drops, the trend of the data demonstrates that the eclipse itself was the primary driver of the decline.

Iceland, Spain and Portugal saw the biggest decreases in traffic  

The figure above shows trend lines for each individual country. The gray triangles represent the progression of the eclipse obscuration, while the red line tracks the amount of traffic changed from its usual baseline. In almost all the countries and regions impacted in the course of the eclipse, traffic made noteworthy changes ranging from 9.3 to -46.7%. 

The right-hand numbers on the “y2”-axis are the obscuration, calculated using precise sun and moon positions. For each location we found the apparent angular sizes of the sun and moon and how far apart they are in the sky, then calculated the fraction of the sun's disk covered by the moon every 5 minutes via the geometric overlap of two circles. That gave each place both its peak obscuration (how deep the eclipse got, 0–100%) and its moment of maximum eclipse. We then summed all regions in each country for the traffic total, and took the average obscuration across a country's regions to place its national max-eclipse time.

To differentiate the eclipse from a typical Wednesday evening, we compared eclipse day against the same weekday: the median of the three previous Wednesdays, matched slot-by-slot on time-of-day. Using the median keeps one odd week from skewing the comparison. Every number is then reported as percent change vs. baseline. When looking at the percentage on the left-hand y-axis, 0% means "totally normal" and negative means "less active than usual."

We can see the changes in traffic beginning in Alaska around 15:35 UTC, where the eclipse began its pathway. Iceland, Spain, and Portugal experienced the most dramatic drops in traffic, whereas Poland and Denmark quickly returned to pre-eclipse levels. Norway and Sweden actually saw slight traffic increases above baseline, while Denmark recorded the least overall change.

Ultimately, these findings reveal a clear correlation between the path of the eclipse and human behavior online. While the severity and duration of traffic drops varied by region, Radar’s HTTP traffic data demonstrates how a shared physical event can temporarily reshape digital activity across an entire continent.

Track the impact of world events on Cloudflare Radar

Major events in the physical world remind us that digital traffic is, at its core, a direct reflection of human attention. When the moon obscured the sun across Europe, the Internet slowed down not because of network failures, but because people paused their online activity to watch. As network patterns quickly normalized post-eclipse, the data left behind offers a fascinating snapshot of how a cosmic event can momentarily realign our online world.

To explore more interactive traffic insights and track how major worldwide events shape internet activity every day, visit Cloudflare Radar or follow us on social media at @CloudflareRadar (X), https://noc.social/@cloudflareradar (Mastodon), and @radar.cloudflare.com (Bluesky).



Read the whole story
emrox
3 days ago
reply
Hamburg, Germany
Share this story
Delete
Next Page of Stories