To migrate from Bitly without breaking links, split your links in two. Links on your own custom domain can move: import the slugs into the new tool, then change one DNS record, and the exact same URLs keep resolving. Links on the shared bit.ly domain cannot move, because Bitly owns that hostname, so you keep a Bitly account alive for as long as those URLs sit in emails, PDFs and print. The import itself takes minutes. The calendar time goes on DNS caching and on a soak period before you cancel anything.
The rest of this guide is the detail that decides whether the move is invisible to visitors: export, field mapping, conflict rules, redirect status, DNS timing, verification from a terminal and rollback. Bitly facts come from Bitly's help center and API reference (accessed 2026-10-02); Elido facts come from the importer and redirect code.
I'm Ana, and I work on migrations at Elido. My rule is simple: decide what can move before you decide how. If you're still choosing a destination, Elido vs Bitly is the feature comparison.
What Can and Cannot Move Off Bitly
A short URL is a hostname plus a slug. You control where it goes only if you control the hostname, which gives three cases and only one real migration.
| Link type | Controls hostname | On migration |
|---|---|---|
bit.ly/slug | Bitly | Cannot move; keeps resolving while Bitly allows it |
links.yourbrand.com/slug | You, via DNS | Moves: import the slugs, then repoint the CNAME |
| Bitly complimentary domain | Bitly | Cannot move; not renewed after you delete or downgrade, so links break on expiry |
For bit.ly links the honest goal is not "move" but "stop creating new ones". Setting up a branded domain before you need to leave is the cheapest insurance in this whole topic.
Step 1: Inventory and Export Your Bitly Links
Start with everything that can break: short links (slug, destination, title, tags and group; one account can own several groups, and a forgotten group is a forgotten domain), every custom domain that serves Bitly links (check your DNS zones, not only the Bitly settings), printed QR codes (a Bitly QR code keeps working as long as its link does, and printed ones are hardest to change) and bio pages (they live on their own URLs and are not in the link export).
Export through the Bitly API with a Generic Access Token, one group at a time. GET /v4/groups/{guid}/bitlinks?size=100 returns a page of links plus a pagination.next URL, and an empty next means you are done:
TOKEN="your-generic-access-token"
GROUP="your-group-guid"
curl -s -H "Authorization: Bearer $TOKEN" \
"https://api-ssl.bitly.com/v4/groups/$GROUP/bitlinks?size=100"
# follow .pagination.next until it comes back empty
The dashboard export depends on your plan and covers only what is on screen, so the API is the reliable route. Short.io's guide to exporting Bitly links notes that free Bitly accounts cannot export from the dashboard at all. While you are there, record each link's lifetime click counter: it is the only click history Bitly gives you, and you need it before cutover.
Step 2: Map Bitly Fields to Elido and Pick a Conflict Rule
Elido's Bitly importer carries four things per link: slug, destination URL (spot-check UTMs on 20), title (cut at 200 characters) and tags, plus an imported:bitly tag for filtering and bulk edits.
What does not travel: lifetime click counters (save them in your own sheet), created dates, QR designs (regenerate with the QR designer), bio pages (rebuild in bio pages), and campaign or deep-link config (recreate as campaigns).
Slug case and the collision trap
Bitly treats bit.ly/CustomWord and bit.ly/customword as different links, which its help center confirms. Elido stores slugs case-insensitively per domain, keeping the imported case, so two Bitly links that differ only by case collide. If bit.ly/Promo points at /spring and bit.ly/promo points at /autumn, Promo imports cleanly and promo conflicts. The conflict rule then decides what happens.
- Suffix (the default) walks
promo-2,promo-3and so on, up to 50 attempts, then reports an error. It silently changes a public URL: every printedpromolink now shows the spring page, and the autumn link sits onpromo-2, a URL nobody printed. - Skip leaves the existing link untouched and records the Bitly row with its slug and the reason.
- Fail stops the whole job at the first clash.
When the printed slug must stay exact, choose skip or fail and resolve each clash by hand.
Step 3: Import Your Links Into Elido
Three routes get links in, depending on size and source.
- Bitly importer. Open Integrations, then the Bitly migration, paste a Generic Access Token, pick the group, a target domain and a conflict rule, and start. The Bitly migration page walks through the form.
- Dashboard bulk and CSV. The New link dialog takes up to 100 URLs per batch, one per line or as CSV (
url,slug,title); bulk import from Google Sheets covers the spreadsheet route. - API.
POST /v1/workspaces/{workspace_id}/links/bulkaccepts up to 100 links per call and reports success or failure per item.
How the importer behaves
Run one job per Bitly group. A job stops at 50,000 links or 30 minutes (guardrails, not a pricing limit), so split larger accounts by group. The token is held in memory for the run and then discarded. Each job reports imported, skipped and failed counts; a partial status means some rows failed, and the error list (capped at 1,000 entries) says which and why. A sweep marks a job failed after 30 minutes without progress. Re-runs are safe under suffix and skip, because links already imported are detected. Resuming from a saved cursor is planned; today an interrupted job is simply re-run.
The same job system runs importers for Rebrandly, Short.io, TinyURL and Dub.
Import a small group first and click through 20 links across your most valuable destinations. A rehearsal costs an afternoon and is where you find the colliding slugs.
The links list after an import, with tags to filter on. DEMO workspace with synthetic example data, not customer results.
Step 4: Cut Over DNS and Keep Redirects Intact
Only links on your own domain need this step. After the DNS change, a request for https://links.yourbrand.com/slug must reach a service that already holds that exact slug, so the import comes first and the DNS change second. Some tools do it the other way round: the Short.io approach points your domain at them first and copies a Bitlink across only when somebody clicks it, so a link nobody clicks during the transition is never transferred. Importing up front avoids that gap.
Registering the domain in Elido gives you a TXT record at _elido-verify.<hostname> and a CNAME to edge.elido.me. The domain verifies when both resolve, and the verifier gives up after 24 hours if either is missing. Since the CNAME is the cutover, verification completes at cutover, not before. The custom domain setup guide shows the forms.
TTL arithmetic
A DNS answer can be cached for as long as the record's TTL says (RFC 1035, section 3.2.1), so the worst-case stale window equals the TTL before the change. A CNAME left at 86400 seconds can keep sending visitors to Bitly for a full day. At D-2, lower the TTL to 300 seconds and write down the current target; Copy it from your own zone: it is your rollback value. On D0, run the production import, then swap the CNAME and add the TXT record. Five to ten minutes later, confirm the domain shows verified and request a link over HTTPS. Keep the TTL at 300 through the soak.
301 vs 302 during the cutover
Bitly documents its links as 301 (permanent) redirects. Elido lets you choose 301, 302 or 307 per link; the importer sets none, so imported links start as 302. That suits the cutover: RFC 9110, section 15.4.2 says a 301 is heuristically cacheable, while a 302 is not cached by default (section 15.4.3). Flip to 301 on day one, then roll back, and every client that cached the answer keeps going to the old place.
Stay on 302 through the soak, then switch links whose destinations will never change to 301 in bulk, selecting them with the imported:bitly tag. 301 vs 302 redirects covers where the SEO difference matters, and Google's redirect documentation is the source. Watch for double hops too: a proxy that forces HTTPS before the request reaches Elido can add one (redirect chains and SEO, redirect loop guide).
Step 5: Verify the Cutover With curl
Never trust a green dashboard; request the real URL. First, confirm DNS from a public resolver rather than your office one:
dig +short CNAME links.yourbrand.com @1.1.1.1
dig +short TXT _elido-verify.links.yourbrand.com @1.1.1.1
Second, look at one redirect without following it: curl -s -o /dev/null -D - --max-redirs 0 https://links.yourbrand.com/SummerSale. You want a 302 (or the status you chose) and a location: header equal to your export; a 404 means the slug was not imported, a 200 means a page, not a redirect.
Third, run every slug from your export through a loop, using a two-column slug,destination CSV built from your Bitly pull:
DOMAIN="links.yourbrand.com"
fail=0
while IFS=, read -r slug dest; do
out=$(curl -s -o /dev/null -w '%{http_code} %{redirect_url}' --max-redirs 0 "https://${DOMAIN}/${slug}")
code=${out%% *}; loc=${out#* }
case "$code" in 301|302|307) ;; *) echo "BAD STATUS $code $slug"; fail=$((fail+1)); continue;; esac
[ "$loc" = "$dest" ] || { echo "MISMATCH $slug -> $loc (want $dest)"; fail=$((fail+1)); }
done < slugs.csv
echo "failures: $fail"
A trailing-slash mismatch is cosmetic: fix the comparison, not the link. Run the loop after the first hour, the next morning and a week later, and test one slug per active channel by hand, in that channel's exact mixed-case spelling.
Sign-off, by someone other than the engineer: imported plus skipped plus failed equals the filtered export; every failed row is fixed or consciously dropped; 50 sampled links keep their UTMs; the top 20 links by lifetime clicks pass a manual click-through; a printed QR code scans; redirects are one hop on valid HTTPS; Bitly lifetime counters are saved with a date.
Start a workspace and run the rehearsal import before you commit to a cutover date, while there is still time to fix collisions calmly.
Step 6: What to Expect in Analytics After Migrating
Click history cannot come across, and no importer can change that. Bitly's API documents two click endpoints per bitlink, GET /v4/bitlinks/{bitlink}/clicks and GET /v4/bitlinks/{bitlink}/clicks/summary, and both return time-bucketed counts, not individual events. Without per-click rows there is no way to rebuild past referrers, countries or devices. Historical clicks you need for reporting belong in GA4 or your own warehouse.
Elido counts clicks from the moment DNS points at it. Before cutover, save each important link's lifetime counter with the date and annotate the cutover on every chart. Then monitor: daily in week 1 for 404s and a click dip against the same weekdays before cutover, weekly after that against your baseline plus the saved counters. The analytics feature page lists what Elido reports natively.
The analytics overview, where you watch clicks per day and per host during the 30 days. DEMO workspace, synthetic data.
Step 7: Keep a Rollback Ready, Then Cancel Bitly Last
You can roll back until you cancel Bitly. Agree the trigger in advance, for example an unexplained click drop above 30% for two days, or any broken top-20 link. The action is to put the old CNAME target back; with a 300-second TTL most resolvers follow within about five minutes, and because you stayed on 302 there are no cached 301s pointing the wrong way. Export links created on Elido after cutover first, since they do not exist in Bitly.
What breaks if you cancel Bitly too early
Bitly's help center is specific, and the order of operations matters. bit.ly links keep working after account deletion and the slugs cannot be reused, but you can no longer edit or redirect them, and you lose their metrics. Custom-domain links keep working only while your DNS still points at Bitly; Bitly stops renewing the SSL certificate, so visitors eventually see a "not secure" warning, and a downgrade (as opposed to deletion) only blocks creating new links on that domain. Complimentary domains are not renewed, so links on them break at expiry, which Bitly puts at one year after issue or last renewal. Everything else goes with the account: QR codes you can no longer edit, Bitly Pages and any reports you did not export.
Move DNS first, confirm with the checks above, and only then cancel or downgrade. Keep the account at least 90 days; what Bitly charges helps you pick the cheapest plan to hold as a safety net.
Related on the Blog
- Set up a custom domain with TLS in 5 minutes
- 301 vs 302 redirects for short links
- Bulk-import short links from a Google Sheet
- Migrate from Rebrandly: branded domain handover without slug loss
- Redirect chains and SEO
Sources: Bitly Help Center articles on account deletion, downgrading, link case sensitivity and 301 redirects, plus the Bitly API reference, accessed 2026-10-02; Elido behaviour read from the importer and redirect code on 2026-10-26.
Frequently asked questions
How long does a Bitly migration take?
Plan for about two weeks of calendar time, even though the import itself runs in minutes. Most of the wait is the DNS TTL lowering (24 hours if your record sat at 86400 seconds) and the soak period before you cancel Bitly. A small account with one custom domain can cut over in a week.
Will my bit.ly links keep working if I migrate away from Bitly?
Yes, but only on Bitly's side. Bitly owns the bit.ly hostname, so you cannot repoint those links at another service. Per Bitly's help center they keep resolving after account deletion, but you can no longer edit or redirect them or see their metrics.
Can I import my Bitly click history?
No. Bitly's API returns aggregated click counts, not per-click events, so no importer can rebuild referrers, countries or devices. Record each link's lifetime counter before cutover and keep it beside the clicks Elido counts from the cutover date.
How do I export all my links from Bitly?
Use the Bitly API with a Generic Access Token and page through each group, 100 links per page. The dashboard export depends on your plan and misses links in other groups. Elido's Bitly importer does this paging for you and only needs a token and a group.
Should I use a 301 or a 302 redirect during the cutover?
Use a 302 (or 307) while you cut over and soak, then switch to 301 only for destinations that are permanent. Browsers and proxies may cache a 301 for a long time, which makes a rollback slower. Bitly itself documents its links as 301 redirects.
What happens to my custom-domain links if I cancel Bitly before moving DNS?
Per Bitly's help center, they keep working only while your DNS still points at Bitly, the SSL certificate is no longer renewed, and visitors eventually see a security warning. You also lose the ability to edit them. Move DNS first, verify, and cancel last.
Try Elido
Paste a URL, get a working short link
No signup. Link lives for 30 days. Sign up to keep it forever.
No signup needed. Sign up free for 50 links a month.