<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>The Halo Journal</title><description>Stories, product news, and field notes from the team building internet for real life.</description><link>https://halowifi.com/</link><item><title>Designing an API that scales to a million captive portals</title><link>https://halowifi.com/blog/designing-an-api-for-a-million-captive-portals/</link><guid isPermaLink="true">https://halowifi.com/blog/designing-an-api-for-a-million-captive-portals/</guid><description>Seven web API design assumptions captive portals break: cloud RADIUS, walled gardens without CDNs, one-shot bootstraps and roaming without a controller.</description><pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A phone joins a network it cannot use yet, opens a strange little browser, and asks us who it needs to be. That happened more than seven million times in the last twelve months, across four continents, against the five regions of Halo Cloud, and every one of those moments lives in a genuinely odd corner of distributed systems: the captive portal, where the assumptions that underpin normal web API design fail one by one.&lt;/p&gt;
&lt;p&gt;Seven of them, by our count. This post walks through each in the order a guest meets them, and it ends where those failures eventually pushed us: writing our own captive portal engine, HaloChilli, because the open-source one the whole industry starts on could not survive the seventh.&lt;/p&gt;
&lt;h2&gt;The constraint that shapes everything: we are the cloud&lt;/h2&gt;
&lt;p&gt;One piece of context first, because it explains why we meet these assumptions harder than most. The typical WiFi vendor serves the captive portal from a box in the venue&apos;s rack: an on-premise controller that hosts the splash page, terminates the login, runs DHCP, and anchors the session. The portal is a LAN hop from the guest. Latency is a rounding error and scale is bounded by the size of the building.&lt;/p&gt;
&lt;p&gt;We made the opposite bet. HaloWiFi is a cloud-managed platform, which means the portal loads from our cloud and the authentication decision, RADIUS, is answered from our cloud too. There is no controller in the rack, on purpose; the reasons live under assumption seven. The consequence is that every design question becomes a latency-and-reliability question. A guest in Kampala or Toronto is not talking to hardware ten metres away; they are talking to infrastructure we run. So we run it close, five regions, guests routed to the nearest, and that flattens the geography. The seven assumptions are what remains.&lt;/p&gt;
&lt;h2&gt;Assumption one: the client is a browser&lt;/h2&gt;
&lt;p&gt;It is not. The captive portal&apos;s client is the OS&apos;s captive network assistant, the mini-browser iOS and Android summon when their connectivity probes fail. It is a hostile runtime: stripped-down, impatient, without the persistence guarantees of a real browser, liable to be dismissed by the user with one swipe, and quick to conclude that the network is broken and give up on the guest&apos;s behalf.&lt;/p&gt;
&lt;p&gt;And everything it does, it does on a network that is, by design, not working.&lt;/p&gt;
&lt;h2&gt;Assumption two: the network underneath you works&lt;/h2&gt;
&lt;p&gt;Ours deliberately does not. The guest is pre-authentication, inside a walled garden that permits exactly one conversation: the one with the portal. Underneath that sits congested venue RF, the worst network path the guest will use all day. Every request you add to the login flow crosses that path, inside a browser that is looking for an excuse to leave.&lt;/p&gt;
&lt;p&gt;The design conclusion is blunt, and it governs everything downstream: the number of network round trips between &quot;phone joins SSID&quot; and &quot;guest is online&quot; is the metric. Everything else in this post serves it.&lt;/p&gt;
&lt;p&gt;The reflexive first move, then, is to get the heavy static assets close to the guest. Push it all to a CDN. Which runs straight into the next broken assumption.&lt;/p&gt;
&lt;h2&gt;Assumption three: static assets are the CDN&apos;s problem&lt;/h2&gt;
&lt;p&gt;For a captive portal they cannot be, and understanding why explains half of our serving architecture.&lt;/p&gt;
&lt;p&gt;The walled garden is a firewall allowlist on the access device: pre-auth guests can reach the portal&apos;s endpoints and nothing else. Modern CDNs are close to un-allowlistable. Their edges live on vast, rotating IP ranges; their certificates and IPs are shared across thousands of co-tenants; the &quot;location&quot; of an asset is deliberately fluid. You can chase their published ranges, but then your garden gate is only as stable as someone else&apos;s network topology. And it is worse than fragile: allowlisting a shared CDN edge quietly allowlists everything else served from it. A pre-auth guest who can reach a whole CDN has a tunnel out of your garden, and free-riders have been exploiting exactly that hole in poorly built portals for years.&lt;/p&gt;
&lt;p&gt;So we serve every byte of the portal ourselves, from our own regional origins, on a small, stable, allowlistable set of endpoints that the access hardware and the cloud agree on. That decision costs us the world&apos;s edge caches, which means we get our performance the older way: by shipping almost nothing. Assets are trimmed to what the theme actually needs and the payload is treated like it is 2005 and every kilobyte is billed. When you cannot lean on somebody&apos;s edge, weight is architecture.&lt;/p&gt;
&lt;p&gt;A light page still has to talk to an API, though. So the next thing we rationed was the talking.&lt;/p&gt;
&lt;h2&gt;Assumption four: round trips are cheap&lt;/h2&gt;
&lt;p&gt;On this path they are the most expensive thing there is, so the API design follows: ask once, receive everything, work locally.&lt;/p&gt;
&lt;p&gt;When a portal instance loads, it makes a single bootstrap request, and the response carries as much as the flow could plausibly need: venue identity and theming, the enabled login methods and their parameters, policy the flow must respect, localisation, and the state of this particular client&apos;s journey so far. From there the flow runs client-side. Screen transitions, validation, method selection, all of it happens without touching the network again. The network is bothered when something real happens: credentials submitted, a code redeemed.&lt;/p&gt;
&lt;p&gt;The same principle killed multi-step logins in our defaults. Every additional step in a portal flow is not just UX friction; it is another opportunity for the mini-browser to time out or the user to swipe away. The default flows are engineered to be one honest interaction long.&lt;/p&gt;
&lt;p&gt;Which holds beautifully, right up until the code running that interaction is not ours.&lt;/p&gt;
&lt;h2&gt;Assumption five: the code calling your API is yours&lt;/h2&gt;
&lt;p&gt;Frequently, it is not. We do not force our portal flows on anyone: venues and partners can build fully custom login experiences against our engine, their brand, their steps, their logic, and they do, elaborately. Which means the most latency-critical screen in our system regularly runs code we did not write, by developers who have not read the guidelines, because nobody reads the guidelines.&lt;/p&gt;
&lt;p&gt;You cannot fix that with documentation. You fix it with the shape of the handover. Before custom code takes over, the engine hands it a complete, structured context: everything the bootstrap knows, already validated, already typed, already localised, the client&apos;s state machine position included. The custom flow starts life holding everything it needs, so its most common mistakes, re-fetching what it already has, guessing at state, improvising extra chatter, are mistakes it never gets pushed toward. The pit of success is carved so that lazy code lands in it.&lt;/p&gt;
&lt;p&gt;We think of it as designing for the API consumer&apos;s worst day, not their best one. The integrations that make us proudest are the ones that misbehave gracefully. But however well anyone&apos;s flow behaves, ours or theirs, none of it is real until RADIUS says so.&lt;/p&gt;
&lt;h2&gt;Assumption six: the client can wait while you do the bookkeeping&lt;/h2&gt;
&lt;p&gt;Not at the gate, it cannot. The access device asks our cloud &quot;may this client pass,&quot; and the Access-Accept that comes back is the moment the walled garden opens. That request is the most latency-sensitive packet in the entire platform, and our rule for it is: the authorization decision must be cheap, and everything expensive must be somewhere else.&lt;/p&gt;
&lt;p&gt;The RADIUS fast path does the minimum work to answer the only question that matters, against state that is already prepared for it. Session records, accounting, analytics, the bookkeeping that makes dashboards useful, all of that is decoupled and can land a few hundred milliseconds later without any guest noticing, because the NAS holds the client&apos;s session state locally the moment access is granted. The cloud closes the loop; it does not sit in the data path. A design that makes a guest wait on a database write it did not need to wait on has its priorities inverted.&lt;/p&gt;
&lt;p&gt;Granting access this way leaves the session state living on the access device that granted it. Which raises the question that ended up reshaping our whole product: what happens to that state when the guest walks?&lt;/p&gt;
&lt;h2&gt;Assumption seven: the session lives somewhere&lt;/h2&gt;
&lt;p&gt;At single-AP scale, it does, and nothing above is remarkable. The problems arrive with size: a resort, a campus, a venue with dozens of access points, where a guest authenticates once at reception and then moves.&lt;/p&gt;
&lt;p&gt;The industry&apos;s standard answer is the on-premise controller. It anchors the guest session, often runs DHCP, and because every AP hangs off it, roaming is &quot;solved&quot; by centralising everything through one box. It is also an extra cost the customer pays before the first guest connects, a sizing decision made on day one that the deployment will outgrow, and a single point of failure sitting in a closet. We refused to build our architecture around selling one.&lt;/p&gt;
&lt;p&gt;The alternative we chose is solution architecture over hardware: let the fleet itself carry the knowledge. Every Halo device, APs, cloud switches, shares authorized-client state with its peers. When a guest who authenticated at the lobby AP appears at the pool AP, that device already knows this client is authorized and admits them automatically. No portal re-splash, no second login, no detour to anywhere before the guest&apos;s music resumes. The session follows the human, and adding the fortieth AP is the same operation as adding the fourth. Easier life for the customer, considerably more complicated engineering for us, which is the correct direction for that trade to flow.&lt;/p&gt;
&lt;p&gt;This is the assumption that broke our tooling. We started, like almost everyone in this space, on CoovaChilli, the venerable open-source captive portal daemon, and it served us well right up to this wall. Its worldview is fundamentally single-device: one NAS, holding its own sessions, making its own decisions. Distributed authorized-state, the thing our roaming model runs on, is not a feature you bolt onto that worldview; it is a different worldview. So we wrote HaloChilli, our own captive portal engine, built from the first line around state that is shared, synchronised, and fast to consult on the access device itself. The name keeps the lineage; the architecture does not.&lt;/p&gt;
&lt;h2&gt;What a million means&lt;/h2&gt;
&lt;p&gt;&quot;A million captive portals&quot; is not one load test; it is the same guest-shaped problem repeated across thousands of venues in different countries, on different regulations, with different login flows, hitting whichever of our five regions is nearest, frequently all at once, because events synchronise humans and humans synchronise load. The architecture above is what makes that shape survivable: serve everything yourself so the garden stays sealed, ask the network for as little as possible, keep other people&apos;s code well-fed and off the hot path, answer the gate question instantly and do the bookkeeping later, and let the fleet share the state a controller would have hoarded.&lt;/p&gt;
&lt;p&gt;None of it is exotic. All of it is the accumulated residue of watching real guests connect on four continents and being unwilling to make any of them wait. If you are building against our platform, the &lt;a href=&quot;/api&quot;&gt;API docs&lt;/a&gt; show what the bootstrap hands you. If you are evaluating us, this post is the level of thinking underneath every feature we ship. And if you just run venues: &lt;a href=&quot;/contact#demo&quot;&gt;book a demo&lt;/a&gt;, and the next phone that joins and asks who it needs to be will get its answer before it finishes asking.&lt;/p&gt;
</content:encoded><category>engineering</category></item><item><title>Live Event WiFi Deployment: The Field Guide</title><link>https://halowifi.com/blog/event-wifi-deployment-guide/</link><guid isPermaLink="true">https://halowifi.com/blog/event-wifi-deployment-guide/</guid><description>How to plan and deploy WiFi for a live event: capacity math, AP counts, RF settings, segmentation, roaming and day-of ops. With a printable checklist.</description><pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Event WiFi has a reputation problem, and it earned it honestly. Most of us have stood in a conference hall watching a spinner, surrounded by two thousand people doing the same. The physics of that room are hard, but they are not mysterious. Almost every event network that falls over falls over for one of a handful of predictable reasons, and every one of them is avoidable at the planning table, days before the first flight case rolls off the truck.&lt;/p&gt;
&lt;p&gt;This guide is the deployment playbook we wish someone had handed us years ago. It is written for the people who actually build these networks: AV and IT contractors, venue technical teams, and the unlucky organiser who just found out that &quot;the WiFi&quot; is now their job. It is hardware-agnostic. Everything in it can be done with any serious equipment, by hand, if you have the time. Where we give numbers, they are opinionated on purpose. Hedge-everything guides do not help anyone at midnight before a load-in.&lt;/p&gt;
&lt;h2&gt;The short version&lt;/h2&gt;
&lt;p&gt;If you read nothing else, deploy against these rules:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Plan for &lt;strong&gt;70 to 80 percent of headcount&lt;/strong&gt; connected at peak for conferences and expos, &lt;strong&gt;40 to 60 percent&lt;/strong&gt; for concerts and social events.&lt;/li&gt;
&lt;li&gt;Budget &lt;strong&gt;2 to 4 Mbps per guest&lt;/strong&gt;. Airtime, not raw bandwidth, is your real constraint.&lt;/li&gt;
&lt;li&gt;Plan around &lt;strong&gt;60 to 100 active clients per radio&lt;/strong&gt;. Ignore the association limit on the datasheet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;More small cells at low power beats fewer loud APs.&lt;/strong&gt; Spread the client load across devices.&lt;/li&gt;
&lt;li&gt;5GHz carries the event. &lt;strong&gt;6GHz is your cleanest spectrum&lt;/strong&gt; where clients support it, but plan for its shorter reach.&lt;/li&gt;
&lt;li&gt;Stay on &lt;strong&gt;narrower channels&lt;/strong&gt; in dense zones. You care about many users connecting reliably, not one user&apos;s speed test.&lt;/li&gt;
&lt;li&gt;Press, production and payments need &lt;strong&gt;priority, not just separation&lt;/strong&gt;. A VLAN alone does not protect them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Roaming quality decides the guest experience.&lt;/strong&gt; A network that cannot hand clients off cleanly is a network that does not work, whatever the throughput numbers say.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Preload the captive portal before doors open&lt;/strong&gt; and size DHCP at twice your expected peak.&lt;/li&gt;
&lt;li&gt;Teardown is part of the deployment, not what happens after it.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The rest of this guide walks the event timeline: plan, stage, install, doors open, show time, teardown.&lt;/p&gt;
&lt;aside&gt;
  &lt;a href=&quot;/downloads/halowifi-live-event-wifi-checklist.pdf&quot;&gt;
    &lt;img src=&quot;/images/blog/event-wifi-checklist-p1-v1.webp&quot; alt=&quot;&quot; /&gt;
  &lt;/a&gt;
  &lt;div&gt;
    &lt;p&gt;Printable · Field series 01&lt;/p&gt;
    &lt;h3&gt;The Deployment Checklist&lt;/h3&gt;
    &lt;p&gt;Two pages that condense all of it for the clipboard: the six phases in order, the numbers that matter, and the red boxes that take networks down when skipped.&lt;/p&gt;
    &lt;p&gt;PDF · 2 pages · A4 · 130 KB&lt;/p&gt;
    &lt;div&gt;
      &lt;a href=&quot;/downloads/halowifi-live-event-wifi-checklist.pdf&quot;&gt;Download the checklist&lt;/a&gt;
      &lt;a href=&quot;/downloads/halowifi-live-event-wifi-checklist.pdf&quot;&gt;Print&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/aside&gt;
&lt;h2&gt;Plan: do the capacity math&lt;/h2&gt;
&lt;p&gt;Every failed event network we have seen was under-planned, not under-specced. The math takes twenty minutes and it decides everything downstream: AP count, placement, channel plan, backhaul contract.&lt;/p&gt;
&lt;h3&gt;How many people will actually connect&lt;/h3&gt;
&lt;p&gt;Attendees are not clients. The take rate depends on the event:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Conferences, expos, trade shows: 70 to 80 percent of headcount at peak.&lt;/strong&gt; These crowds are working. Laptops, phones and often a tablet per person, and they arrive expecting to upload, demo and video-call.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Concerts, weddings, social events: 40 to 60 percent.&lt;/strong&gt; People are there for the event, not the internet, but the spikes are sharper: doors, intermission, the headline moment when ten thousand phones start uploading video simultaneously.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Err on the high side. At any large gathering the cellular network degrades as towers saturate, which pushes people onto your WiFi precisely when it is busiest. Your network inherits the carriers&apos; failure.&lt;/p&gt;
&lt;p&gt;Each connected person also brings more than one radio. Count 1.2 to 1.5 devices per connected attendee at a working event once laptops and wearables join.&lt;/p&gt;
&lt;h3&gt;How much per client&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;2 to 4 Mbps per general guest&lt;/strong&gt; covers messaging, social, uploads and standard-definition streaming comfortably. Resist the urge to promise more. The constraint in a dense room is not the pipe, it is airtime: every transmission occupies the channel for everyone on it, and a handful of clients pulling 50 Mbps can starve a hundred clients trying to load a boarding pass. Per-client rate limiting is not stinginess, it is fairness enforcement, and it is the single most effective quality lever you have.&lt;/p&gt;
&lt;h3&gt;Clients per radio&lt;/h3&gt;
&lt;p&gt;Datasheets love to advertise 200+, sometimes 500+, associated clients per access point. Association is not service. The most misleading number in event WiFi is the association limit, because an AP can hold hundreds of idle associations while delivering usable service to a fraction of them.&lt;/p&gt;
&lt;p&gt;Plan around &lt;strong&gt;60 to 100 active clients per radio&lt;/strong&gt;, and use the lower end of that range for zones where clients are doing real work (a press pit, a demo floor) and the higher end for zones where most traffic is light and bursty.&lt;/p&gt;
&lt;h3&gt;A worked example: 2,000-person expo&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Headcount&lt;/td&gt;
&lt;td&gt;2,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Expected peak take rate&lt;/td&gt;
&lt;td&gt;75% → 1,500 people&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Devices per connected person&lt;/td&gt;
&lt;td&gt;1.3 → ~1,950 clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-client budget&lt;/td&gt;
&lt;td&gt;3 Mbps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Planning load per radio&lt;/td&gt;
&lt;td&gt;80 clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Radios required&lt;/td&gt;
&lt;td&gt;~25&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dual-band/tri-band APs required&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;14 to 18, placed by zone&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Zone it rather than averaging it. The entry hall takes the association storm at doors. The main floor holds the sustained load. The food court peaks at lunch, the keynote room peaks twice a day and is empty otherwise. An even grid of APs is a plan for an even crowd, and there is no such thing.&lt;/p&gt;
&lt;p&gt;Backhaul sizing falls out of the same numbers, with one mercy: not everyone transmits at once. A 10:1 to 20:1 oversubscription against the theoretical sum is normal. For this expo, 300 to 500 Mbps of real, tested backhaul is a sane target. (Provisioning the backhaul itself is out of scope for this guide; we are assuming you have a line, bonded cellular, or fibre already arranged.)&lt;/p&gt;
&lt;h3&gt;How this changes by event type&lt;/h3&gt;
&lt;p&gt;The framework holds everywhere; the numbers and the failure modes move. What to expect:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event type&lt;/th&gt;
&lt;th&gt;Take rate&lt;/th&gt;
&lt;th&gt;Spike shape&lt;/th&gt;
&lt;th&gt;Dominant zone&lt;/th&gt;
&lt;th&gt;Hardest problem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Expo / trade show&lt;/td&gt;
&lt;td&gt;70 to 80%&lt;/td&gt;
&lt;td&gt;Doors surge, then sustained all day&lt;/td&gt;
&lt;td&gt;Demo floor&lt;/td&gt;
&lt;td&gt;Exhibitor and press uplink surviving guest load&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conference&lt;/td&gt;
&lt;td&gt;70 to 80%&lt;/td&gt;
&lt;td&gt;Synchronised: every break moves everyone at once&lt;/td&gt;
&lt;td&gt;Keynote hall&lt;/td&gt;
&lt;td&gt;Roaming as rooms empty and refill in minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Concert / festival&lt;/td&gt;
&lt;td&gt;40 to 60%&lt;/td&gt;
&lt;td&gt;Extreme bursts: doors, intermission, encore&lt;/td&gt;
&lt;td&gt;Pit and GA front&lt;/td&gt;
&lt;td&gt;Association storms plus a wall of body attenuation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wedding / social&lt;/td&gt;
&lt;td&gt;40 to 60%&lt;/td&gt;
&lt;td&gt;Photo moments and speeches&lt;/td&gt;
&lt;td&gt;One room&lt;/td&gt;
&lt;td&gt;Photographer and vendor priority on a modest pipe&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Read your event&apos;s row, then apply the rest of the guide with those numbers in hand.&lt;/p&gt;
&lt;h2&gt;Plan: placement and the empty-venue lie&lt;/h2&gt;
&lt;p&gt;Two principles carry almost every placement decision.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More small cells at low power beats fewer loud APs.&lt;/strong&gt; It is tempting to cover a hall with four APs at full transmit power. Coverage will look perfect on the survey. Then the room fills, all four radios saturate, and there is nowhere for the load to go. Many APs at low power (10 to 14 dBm, roughly matching a phone&apos;s transmit power) create small cells that spread the client load across many radios, which is the entire game. A client five metres from a quiet AP gets better service than a client thirty metres from a loud, drowning one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The empty venue lies to you.&lt;/strong&gt; A human body is 3 to 5 dB of attenuation at these frequencies; a crowd is a wall of water. The pristine coverage map you measured on Wednesday afternoon does not exist on Saturday night. Mount APs overhead wherever rigging allows, so signals travel over the crowd instead of through it. Tripod-mounted APs at head height are a last resort; they serve the ten people standing nearest and lose everyone behind them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overhead has a ceiling, literally.&lt;/strong&gt; Expo halls and arenas often put the rigging at 10 metres or more, and every metre of height is distance you have inserted between the AP and every client it serves. The trap is that the failure is asymmetric: the AP transmits with decent power through a decent antenna, but the phone answers with a fraction of that through a terrible antenna held against a body. A high-mounted network surveys beautifully, because a survey measures the downlink, and then collapses under load as uplink retries pile up. So the placement ladder is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;3 to 6 metres is the sweet spot&lt;/strong&gt;: trussing, poles, columns, booth structures. Above the crowd, still within reach of a phone&apos;s weak uplink. At an expo, booth builds and pipe-and-drape rigs give you this for free if you claim the positions early.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If the ceiling is all you get, change the antenna, not the strategy.&lt;/strong&gt; Directional patch or narrow-beam antennas aimed down claw back the path loss with gain, and their tight footprint recreates the small, defined cells that height otherwise destroys. This is how arenas do it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;What you never do is hang omnidirectional APs at 10-plus metres.&lt;/strong&gt; An omni at height creates one giant, sloppy cell that hears clients from three zones away, which undoes the entire small-cell plan in a single mounting decision.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Survey with the staging in place if you possibly can. LED walls, metal trussing and scaffolding reshape propagation, and they usually arrive after the site visit.&lt;/p&gt;
&lt;h2&gt;Stage: configure in the warehouse, not the venue&lt;/h2&gt;
&lt;p&gt;The venue gives you hours; the warehouse gives you days. Every minute of on-site configuration is a minute stolen from the things you can only do on site: physical placement, cable runs, and verification.&lt;/p&gt;
&lt;p&gt;Before the truck leaves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Every AP configured, named by zone, firmware-matched and labelled to match the floor plan.&lt;/li&gt;
&lt;li&gt;SSIDs, VLANs, rate limits and RADIUS/portal settings applied and tested against a bench setup.&lt;/li&gt;
&lt;li&gt;A printed (yes, printed) floor plan with AP positions, channel assignments and switch port mapping. Venues eat laptop batteries and cellular coverage.&lt;/li&gt;
&lt;li&gt;Spares: at least 10 percent extra APs, pre-configured as hot swaps, plus the cables, injectors and mounts to deploy them.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The install-day test is simple: if a box can be plugged in by someone who has never seen the configuration, staging was done right.&lt;/p&gt;
&lt;h2&gt;Install: RF settings that survive a crowd&lt;/h2&gt;
&lt;p&gt;The dense-venue RF playbook is short and unglamorous, and skipping any line of it is how networks die at 2pm on day one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5GHz carries the event.&lt;/strong&gt; It has the channels, the client support and the capacity. Design as if it is the only band, then treat everything else as auxiliary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deploy 6GHz where you can.&lt;/strong&gt; WiFi 6E and WiFi 7 clients now make up a meaningful share of any professional crowd, and 6GHz is the cleanest spectrum at any event: no legacy devices, no hotspot pollution, wide open channels. Its physics cut both ways, though. 6GHz propagates noticeably shorter range than 5GHz and gives up more to obstruction, so it is not a drop-in replacement: plan tighter cell spacing for it, or treat it as a capacity layer in your densest zones (press areas, demo floors) rather than a coverage layer. Offloading the newest, most capable clients onto 6GHz also quietly relieves 5GHz for everyone else. One interaction to respect: 6GHz is the most height-sensitive band of the three, so it pays the high-ceiling penalty hardest. If your only mounting option is up high, 6GHz needs the directional-antenna treatment even more than 5GHz does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2.4GHz is either off or quarantined.&lt;/strong&gt; At an event it is a war zone of personal hotspots, Bluetooth and wireless production gear. If legacy devices or payment terminals need it, give it a dedicated SSID at minimum power and keep guests off it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Stay narrow on channel width.&lt;/strong&gt; 20MHz channels in dense zones is our default, 40MHz where density is moderate. Wide channels buy individual throughput at the cost of channel reuse, and at an event you care much less about each user&apos;s throughput than about the number of users the room can hold cleanly. This one is genuinely subjective, and if your event is a small workshop where forty people need fast transfers, go wide. In a dense hall, go narrow and take the reuse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Kill the legacy floor.&lt;/strong&gt; Disable 802.11b rates and set the minimum basic rate to 12 or 24 Mbps. Slow clients transmit for longer, and airtime is the shared resource; one 1 Mbps client at the edge of a cell degrades the channel for everyone on it. Set a minimum RSSI so clients are nudged to a nearer AP instead of clinging to a distant one.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cap the SSID count.&lt;/strong&gt; Every SSID beacons on every radio, and beacons are pure overhead. Three to four SSIDs per radio is a sane ceiling; each additional one taxes every client in range whether they use it or not.&lt;/p&gt;
&lt;h2&gt;Install: segmentation, and why a VLAN is not enough&lt;/h2&gt;
&lt;p&gt;An event network is at least four networks wearing one set of hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Guest&lt;/strong&gt;: isolated client-to-client, rate-limited, internet-only.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Production&lt;/strong&gt;: show control, streaming encoders, AV. Never shares airtime priority with guests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Press and photographers&lt;/strong&gt;: their uploads are the event&apos;s public record, on deadline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payments and POS&lt;/strong&gt;: small traffic, zero tolerance for failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;VLAN separation is the obvious first step, and it is not sufficient. A VLAN gives press their own broadcast domain and address space, but at the radio and the uplink they are still queuing behind two thousand guests. Separation without prioritisation just means their traffic fails on its own dedicated network.&lt;/p&gt;
&lt;p&gt;The classes that matter need actual QoS: WMM priority at the radio, queue priority at the switch and gateway, and bandwidth reservations that hold under guest saturation. The test is brutal and simple: at absolute peak guest load, can a photographer push a 2GB card to an editor, and does a card machine complete a transaction on the first try? If the answer depends on how busy the guests are, the segmentation is decorative.&lt;/p&gt;
&lt;p&gt;Where the venue allows it, put press and production on their own radios or their own band entirely (this is a natural use of that 6GHz capacity layer). Airtime you never contend for is the only airtime you can promise.&lt;/p&gt;
&lt;h2&gt;Doors open: surviving the surge&lt;/h2&gt;
&lt;p&gt;Guests forgive a queue at the bar; they never forgive a login page that will not load. The first ten minutes after doors are the network&apos;s real stress test, and it is not a bandwidth test, it is an onboarding test.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;DHCP first.&lt;/strong&gt; Size the pool at &lt;strong&gt;twice your expected peak associations&lt;/strong&gt;, with leases of 30 to 60 minutes. Gate churn, people connecting, wandering out for a call, reconnecting, exhausts tight pools fast, and DHCP exhaustion presents as &quot;the WiFi is broken&quot; while every dashboard shows green.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The captive portal is the perceived quality of the entire network.&lt;/strong&gt; Whatever the backend, the splash page must be paint-fast and lightweight, and it must be warm before the first guest arrives, not compiling itself when the first phone connects. If the portal stack has a cold-start behaviour, trigger it yourself before doors. Keep the page under a couple of hundred kilobytes, host its assets locally or on fast edge infrastructure, and make the auth flow survive a thousand submissions in a ten-minute window. A beautiful portal that takes eight seconds to render has already told every guest the network is broken, regardless of what the network can actually do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Watch the walk-in on a live view.&lt;/strong&gt; Association counts per AP during the first thirty minutes tell you immediately whether the load is spreading the way the plan said it would, and doors-open is when a mis-aimed antenna or a dead switch port announces itself.&lt;/p&gt;
&lt;h2&gt;Show time: roaming is the whole ballgame&lt;/h2&gt;
&lt;p&gt;Here is the uncomfortable truth about dense-venue WiFi: you can get every setting above right and still deliver a miserable experience if roaming is broken. Event guests move constantly, between halls, to the food court, back for the keynote, and every one of those walks is a series of handoffs between access points.&lt;/p&gt;
&lt;p&gt;The failure mode is the &lt;strong&gt;sticky client&lt;/strong&gt;: a phone that associated at the entrance and clings to that AP from across the building, hammering out retries at the lowest rates, degrading its own experience and burning airtime for everyone still near the door. Multiply by a few hundred and a well-designed network performs like a broken one.&lt;/p&gt;
&lt;p&gt;Well-implemented roaming is paramount, and it is a system property, not a checkbox:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;802.11k and 802.11v on, always.&lt;/strong&gt; Neighbour reports and BSS transition steering give clients the information and the nudge to move to the right AP before they degrade.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;802.11r (fast transition) is worth it, tested.&lt;/strong&gt; It cuts re-authentication during handoff to near-imperceptible, which matters enormously on portal- or RADIUS-authenticated networks. But it still confuses some older clients, so test with the oldest devices you realistically expect in the crowd before you commit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Minimum RSSI and band steering&lt;/strong&gt; do the pushing where clients will not listen: shed clients that have drifted too far, and lift capable clients up to 5 and 6GHz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistent everything.&lt;/strong&gt; Same SSID, same security, same VLANs everywhere the client roams. Any inconsistency between APs turns a 50-millisecond handoff into a full reconnect through DHCP and the portal, in the middle of someone&apos;s video call.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Walk the floor during the event with a phone and watch it hand off. If you can cross the venue on a video call without a stutter, the network is doing the hardest thing it will be asked to do.&lt;/p&gt;
&lt;h2&gt;Show time: operating from the floor&lt;/h2&gt;
&lt;p&gt;Nobody at a live event is sitting at a NOC. Whoever is watching the network is doing it from a phone, standing behind a stage, mid-conversation with a stressed producer. Plan the observability accordingly:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One live view: active clients, per-AP load, uplink utilisation. Big numbers, glanceable.&lt;/li&gt;
&lt;li&gt;Alerts pushed, not polled: an AP going dark should find you; you should not be refreshing dashboards to find it.&lt;/li&gt;
&lt;li&gt;The mid-event fixes worth knowing by heart: swap a failed AP for a pre-configured spare, drop transmit power in a zone where cells are colliding, tighten guest rate limits when the uplink runs hot, and steer around a saturated zone by nudging minimum RSSI. Every one of these is a two-minute change if it was staged, and a truck roll if it was not.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Teardown: end it like you mean it&lt;/h2&gt;
&lt;p&gt;The event ends; the network&apos;s obligations do not, unless you end them deliberately. Teardown is a feature of the deployment, not a footnote:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Access codes and portal sessions expire when the event does. Nothing left open, nothing to remember to close.&lt;/li&gt;
&lt;li&gt;Guest data has a retention story. A pop-up network should keep data for days, not quietly forever, and whatever the organiser needs (attendance, portal analytics, sponsor reporting) should be exported and delivered as a wrap-up report before the data ages out.&lt;/li&gt;
&lt;li&gt;Hardware comes back tested and reset, and the event&apos;s configuration is archived, because the fastest way to plan the next event is to clone the last one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The next event deserves a clean slate, and so does this one&apos;s data.&lt;/p&gt;
&lt;h2&gt;Doing all of this without doing all of this&lt;/h2&gt;
&lt;p&gt;Everything in this guide can be built by hand, and for years that is exactly how we did it. It is also exactly why we built Live Events into Halo Cloud: an event becomes an object with a start and an end, any device you plug in on site finds its event and configures itself, the portal is themed once and preloaded before doors, the live capacity view is designed for a phone held in one hand behind a stage, and when the event ends the teardown, code expiry and wrap-up report happen on their own. If you would rather spend load-in day on placement and cable runs instead of configuration, &lt;a href=&quot;/features&quot;&gt;that is what it is for&lt;/a&gt;. And if you are running an event soon, &lt;a href=&quot;/contact#demo&quot;&gt;book a demo&lt;/a&gt; and we will spin up a pop-up network live on the call.&lt;/p&gt;
</content:encoded><category>guides</category></item><item><title>Opening our API, or: how we learned to stop worrying and love other people&apos;s code</title><link>https://halowifi.com/blog/opening-our-api/</link><guid isPermaLink="true">https://halowifi.com/blog/opening-our-api/</guid><description>The two fears that almost kept our API closed, why both were wrong, and how opening it made the platform safer and bigger than we would have built alone.</description><pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Every platform team has the meeting. Someone proposes opening the API, properly opening it, documented, supported, for anyone to build on, and the room fills with reasons to wait. We had that meeting, and we had exactly two fears worth taking seriously. Both turned out to be wrong, and both were wrong in ways that taught us more than being right would have. This is the field log.&lt;/p&gt;
&lt;h2&gt;Fear one: the API is safer hidden&lt;/h2&gt;
&lt;p&gt;The argument felt responsible at the time: the API existed for our own portal and apps, nobody else knew its shape, and keeping it that way was a form of protection. Publishing documentation felt like publishing a map.&lt;/p&gt;
&lt;p&gt;Here is what that fear actually was, once we looked at it honestly: hope, dressed up as a security posture. Hiding an endpoint is not a security layer; it is a security delay. Anyone who can join a network and open a developer console can watch our own portal talk to our own API, which means the map was already published to anyone curious enough to look. Security that depends on people not finding your endpoints is not architecture. It is optimism with a firewall.&lt;/p&gt;
&lt;p&gt;The uncomfortable admission is that the fear was doing a job for us: it let us defer work the architecture owed regardless. We always had a real authentication layer, that was never the gap. The gap was the worldview behind it: the API had been designed for one trusted consumer, us. Auth built for a single, well-behaved, first-party caller quietly leans on the caller&apos;s good behaviour, and the API&apos;s privacy gets counted as part of the security story even though it was never a load-bearing part.&lt;/p&gt;
&lt;p&gt;Deciding to open the API meant deciding that every caller is untrusted, and rebuilding the model around that assumption: the same gates, the same limits, the same isolation for every caller, no matter whose name is on the request.&lt;/p&gt;
&lt;p&gt;And here is the part we did not expect, and the reason this post exists: once we made the decision, the work was not the mountain the fear had promised. The dread was expensive; the engineering was not. The fear had been costing us more than the fix.&lt;/p&gt;
&lt;p&gt;The lasting consequence is the principle we now hold hardest: we are zero trust for ourselves, exactly as we are for every customer. Our own portal, our own apps, our own dashboards are just API consumers. No privileged backdoors, no internal-only side doors that partners cannot see. We eat at the same table we serve, which means every improvement the public API earns, first-party inherits, and every claim we make about the API&apos;s security is a claim we stake our own product on. That is a far stronger security statement than obscurity ever was, and it is checkable, which obscurity never was.&lt;/p&gt;
&lt;h2&gt;Fear two: we will lose control of the experience&lt;/h2&gt;
&lt;p&gt;This one wore better clothes. It sounded like product craft: we have opinions about how guest WiFi should feel, we sweat the flows, and handing partners an API means handing them the ability to build something worse and put our engine behind it.&lt;/p&gt;
&lt;p&gt;With some distance, we can name that fear for what it was: myopic, and more than a little self-aggrandising. &quot;Protecting the experience&quot; assumed we had already imagined every experience worth having, that the ceiling of the product was the ceiling of our own imagination. A platform whose experiences are bounded by its makers&apos; foresight is not a controlled product; it is a small one.&lt;/p&gt;
&lt;p&gt;The evidence against the fear was not long in coming. We wrote in &lt;a href=&quot;/blog/designing-an-api-for-a-million-captive-portals&quot;&gt;the previous engineering post&lt;/a&gt; about partners building fully custom login flows against our engine, their brand, their steps, their logic, and doing it elaborately. Those flows are not degraded versions of what we would have built. Many of them are things we would never have prioritised, for markets and workflows we were not staring at, and some of them taught us what the platform actually was. The moments that changed our minds were the integrations we could not have specified, because we did not know enough to specify them.&lt;/p&gt;
&lt;p&gt;Then partners went further than flows. Linkbase, who run guest WiFi for short-term rentals in Canada, built a full API integration: they and their property clients manage every one of their networks from Linkbase&apos;s own dashboard, inside the web app where the rest of their rental operation already lives. The experience we were so worried about protecting? For their vertical, they replaced it wholesale, and theirs is the right one, because a host managing a rental at 11pm wants one pane of glass, not two. Cloud-Fi, our partner in Uganda, went a different direction entirely: an Android app they hand to their own customers, who use it to manage venues and watch revenue collection and disbursement, an operating business with money moving through it, built on top of us. We did not design either of those experiences. We could not have. One replaced our interface and the other turned our platform into the plumbing of someone else&apos;s product, and both are better arguments for the API than anything we shipped ourselves.&lt;/p&gt;
&lt;p&gt;Control, it turns out, was never the valuable thing. The valuable thing was the floor: making the worst integration a partner can build still safe, still fast, still respectful of the guest. So that is where our opinions went. Instead of gatekeeping the experience, we engineered its minimums: the one-shot bootstrap that hands custom code everything it needs before it can improvise, the structured context that makes the lazy path and the correct path the same path, the guardrails that hold when the guidelines go unread. We stopped trying to be the author of every experience and became the physics of all of them. Physics scales better than authorship.&lt;/p&gt;
&lt;h2&gt;What the bomb turned out to be&lt;/h2&gt;
&lt;p&gt;The Strangelove joke in the title is only half a joke. The bomb, the thing we feared and learned to love, is other people&apos;s code running against our platform, permanently, at the most latency-critical moments we have. It is still slightly terrifying, and it should be; healthy platforms stay a little afraid of their consumers.&lt;/p&gt;
&lt;p&gt;But the ledger is not close. Fear one, faced, made the platform safer than hiding ever could, and made us our own strictest customer. Fear two, faced, made the platform bigger than our roadmap, and turned partners into a source of product direction we could not have hired. The API is open, the fears were mirrors, and the only regret is the time we spent in the meeting.&lt;/p&gt;
&lt;p&gt;If you want to see what the platform hands your code before you write a line of it, the &lt;a href=&quot;/api&quot;&gt;API docs&lt;/a&gt; are where we would start. Build something we did not imagine. At this point, we are counting on it.&lt;/p&gt;
</content:encoded><category>engineering</category></item><item><title>Extending guest WiFi with a third-party extender</title><link>https://halowifi.com/blog/extend-guest-wifi-captive-portal/</link><guid isPermaLink="true">https://halowifi.com/blog/extend-guest-wifi-captive-portal/</guid><description>Stretch the guest network behind the captive portal with a TP-Link, Netgear or OpenWrt extender — and the three mistakes that break the portal.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A third-party extender can stretch your guest network into the rooms your HaloWiFi AP can&apos;t reach — with every client still behind the captive portal. The setup is three settings on the extender; the failures are always the same three mistakes. This guide covers both, plus which devices actually work.&lt;/p&gt;
&lt;p&gt;The short version: put the extender in &lt;strong&gt;AP/bridge mode&lt;/strong&gt;, match the &lt;strong&gt;Guest SSID exactly&lt;/strong&gt; (open, no password), and make sure the extender &lt;strong&gt;never runs DHCP or NAT&lt;/strong&gt;. Do that, and a client behind the extender is indistinguishable from a client on the main AP — same DHCP lease, same portal login, same session tracking.&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;The extender is a dumb radio. It rebroadcasts the Guest SSID and bridges every frame back to the HaloWiFi LAN — no routing, no NAT, no DHCP of its own. Everything that makes guest WiFi &lt;em&gt;guest WiFi&lt;/em&gt; stays on the HaloWiFi router, unchanged: DHCP address assignment, captive-portal interception (HaloChilli), RADIUS authentication, session tracking, bandwidth quotas and analytics. The extender is invisible to the portal logic.&lt;/p&gt;
&lt;p&gt;Backhaul matters more than brand. Run an Ethernet cable from the extender to any LAN port on the HaloWiFi router or a downstream switch. Wireless backhaul works, but on single-radio extenders it halves effective throughput and adds a roaming variable — every permanent deployment should use cable.&lt;/p&gt;
&lt;div&gt;&lt;p&gt;&lt;strong&gt;One ESSID per extender.&lt;/strong&gt; A HaloWiFi router broadcasts two networks at once — the open Guest network (captive portal) and the password-protected Staff/PSK network. A third-party extender can only rebroadcast one of them. This guide extends the Guest ESSID; the Staff branch is covered in step 4.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;The topology&lt;/h2&gt;
&lt;figure&gt;





InternetISP / WAN


WAN
HaloWiFi RouterCaptive Portal (HaloChilli)RADIUSDHCP / DNSDirect APGuest ESSID


Ethernet
ExtenderAP / bridge modeGuest SSID · open · no DHCP



Guest Devicesees captive portal

captive portal auth (HaloChilli → FreeRADIUS)
also broadcasts Guest SSID directly

&lt;figcaption&gt;The extender bridges radio coverage; every control-plane function stays on the router.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote&gt;
  &lt;p&gt;From the router’s perspective, a client behind the extender looks identical to a client on the main AP — same DHCP range, same RADIUS session, same portal flow.&lt;/p&gt;
  &lt;cite&gt;Field notes, deployment team&lt;/cite&gt;
&lt;/blockquote&gt;
&lt;h2&gt;What the extender must never do&lt;/h2&gt;
&lt;p&gt;Three failures account for nearly every broken extender deployment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Double NAT.&lt;/strong&gt; The extender must not create its own subnet. If it does, HaloChilli can&apos;t see the client&apos;s real IP and the captive-portal redirect fails completely — clients get a connection error instead of the login page.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Its own DHCP.&lt;/strong&gt; Only the HaloWiFi router assigns addresses. A live DHCP server on the extender hands out out-of-range IPs, breaking RADIUS accounting, bandwidth control and analytics. Re-check after every firmware update — some devices silently re-enable it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hiding client MACs.&lt;/strong&gt; Sessions are tracked by the client&apos;s original MAC address. Mesh systems that forward all traffic behind the node&apos;s own MAC break per-device session isolation, time limits and quotas for everyone on that extender.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Two softer rules: broadcast exactly one SSID (the one you chose to extend — never both), and match the Guest SSID string exactly, case-sensitive, with security set to &lt;strong&gt;Open / None&lt;/strong&gt;. A mismatched SSID is a second visible network that bypasses portal auth.&lt;/p&gt;
&lt;h2&gt;Setup in six steps&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Put the extender into AP / bridge mode.&lt;/strong&gt; In the extender’s web UI or app, switch the operating mode to Access Point (sometimes “AP mode” or “bridge”). This disables its router and NAT functions. Do not use “Range Extender” or “Repeater” mode — those create a second subnet and break the portal.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Disable the extender’s DHCP server.&lt;/strong&gt; Many devices do this automatically in AP mode — confirm it under LAN/Network settings. The DHCP field should read Disabled before you continue.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Connect the backhaul cable.&lt;/strong&gt; Ethernet from the extender’s LAN or WAN port into any LAN port on the HaloWiFi router or a switch on its LAN. Cat5e or better; for ceiling mounts, a PoE switch powers the extender over the same cable.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Match the Guest SSID.&lt;/strong&gt; Set the extender’s SSID to exactly the HaloWiFi Guest network name, security Open / None. The Guest network is open by design — the captive portal does the authenticating.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Verify the client IP.&lt;/strong&gt; Join the extender’s SSID with a test device. It should get an address in the HaloWiFi DHCP range (typically 192.168.182.x). Anything like 192.168.0.x or 10.0.0.x means the extender’s DHCP is still on — back to step 2.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Confirm the portal appears.&lt;/strong&gt; Browse to any HTTP site (e.g. http://example.com) — the HaloWiFi portal login should load; complete a test login end-to-end. HTTPS sites show a certificate error before the redirect can fire, so always test with plain HTTP.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;p&gt;&lt;strong&gt;Extending the Staff/PSK network instead?&lt;/strong&gt; Same steps, different step 4: match the Staff SSID and set WPA2-Personal (or WPA3) with exactly the same passphrase. There is no captive portal on that ESSID — the password is the gate. Never leave an extender SSID open on the Staff segment; that would be uncontrolled access.&lt;/p&gt;&lt;/div&gt;
&lt;h2&gt;Device compatibility&lt;/h2&gt;
&lt;p&gt;From venue deployments so far — treat unlisted devices as untested and verify MAC passthrough plus true AP mode before installing:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Works in AP mode&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TP-Link RE series&lt;/strong&gt; — Tether app or web UI: Settings → Operation Mode → Access Point. Disable DHCP under LAN settings. MAC passthrough confirmed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Netgear EX series&lt;/strong&gt; — use AP mode, not Range Extender mode (settings at 192.168.1.250). Disable DHCP under LAN Setup.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GL.iNet / OpenWrt&lt;/strong&gt; — full control: disable DHCP, set &lt;code&gt;network.lan.proto=none&lt;/code&gt;, disable firewall forwarding. The most flexible option for technical deployments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Conditional&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TP-Link Deco&lt;/strong&gt; — must be switched to Access Point mode in the app &lt;em&gt;before&lt;/em&gt; joining the network; mesh mode hides client MACs. Verify DHCP is off after the mode change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Netgear Orbi&lt;/strong&gt; — AP mode exists on RBR/RBS; older firmware lacks MAC passthrough, so check versions first.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generic OpenWrt&lt;/strong&gt; — configure as a dumb AP via LuCI/UCI: no gateway/DNS on the LAN interface, dnsmasq off, wireless bridged to LAN.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Do not use&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Amazon Eero / Google Nest WiFi&lt;/strong&gt; — neither offers true bridge mode; both always create a second subnet and hide client MACs, which kills the portal redirect for every client behind them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Single-radio budget extenders&lt;/strong&gt; — one radio shared between clients and backhaul halves throughput, and most can&apos;t do true AP mode at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;When something&apos;s not right&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Portal not appearing&lt;/strong&gt; — test with an HTTP (not HTTPS) site; confirm the client IP is in the 192.168.182.x range; confirm AP mode (not router/NAT) and that no second DHCP server is live.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wrong client IP&lt;/strong&gt; — the extender&apos;s DHCP is active. Disable it, reboot the extender, reconnect. Firmware updates are the usual culprit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Per-device limits not enforcing&lt;/strong&gt; — the extender is in mesh mode and hiding MACs. Switch to true AP/bridge mode; verify with a capture that the &lt;em&gt;client&lt;/em&gt; MAC appears on the LAN.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Clients get uncontrolled access&lt;/strong&gt; — the extender SSID is bridged to the wrong segment and has bypassed HaloChilli. Re-bridge onto the Guest LAN and confirm NAT is off.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;When to stop extending&lt;/h2&gt;
&lt;p&gt;Extenders work, with caveats you now know: no RF telemetry, no fast roaming, and settings that need re-checking after firmware updates. A second HaloWiFi AP removes all three — full cloud visibility, zero MAC-passthrough concerns, and seamless portal roaming: HaloWiFi APs in one deployment share 802.11r keys automatically through the cloud controller, so handoffs take ~50 ms. A third-party extender on the same SSID forces a full re-association — a 150–300 ms drop — every time a client walks between radios.&lt;/p&gt;
&lt;p&gt;If the extender is a stopgap, it&apos;s a good one. If coverage is the actual problem, the second AP is the actual fix — and it&apos;s managed from the same dashboard as the first. Questions either way: &lt;a href=&quot;mailto:support@halowifi.com&quot;&gt;support@halowifi.com&lt;/a&gt;.&lt;/p&gt;
</content:encoded><category>guides</category></item></channel></rss>