Who was actually in your Instagram life?

Almost your entire Instagram social graph lives in two files, and none of its history does. Here is every relationship list your export really contains, the set arithmetic that turns them into answers, and the three things it can never tell you.

Almost your entire social graph is two files. followers.json and following.json hold
every follow edge that exists right now. Most of what else is in the connections folder is a
small annotation on those same people - close friends, favourites, muted, restricted. Three
lists break that pattern, because they name people who are in neither file: the accounts you
have requested to follow, the accounts that have requested you, and the ones Instagram has
suggested or pushed at you.

The interesting part is not the files. It is the arithmetic between them. Mutuals,
fans and the people you follow who do not follow back are not stored anywhere; they are
produced by subtracting one list from another, which takes microseconds and tells you
something true. And almost none of it is history: the export is a snapshot of current
state, so it can tell you who follows you and cannot tell you when they started.

  1. 20syou know which two files hold everything.
  2. 3minyou can read the mutual/fan/unfollowed split yourself.
  3. 10minyou know which four questions this folder can never answer, so you stop expecting it to.
2files carry the whole graphfollowers.json and following.json, plus numbered shards of each when the list is long enough.
3views are pure subtractionFans, people-you-follow-who-do-not-follow-back, and mutuals. None of the three is stored by Instagram.
4levels of date certaintyWe label every relationship date with where it came from rather than printing a date we cannot defend.

The two files that carry almost your whole social graph

Open the connections folder in your export and ignore almost everything in it. Two files
matter.

title="followers.json / followers_1.json … followers_N.json"

Every account that currently follows you, with a username and a profile_name. When your
follower list is long enough, Instagram splits it into numbered shards rather than writing one
very large file — followers_1.json, followers_2.json and so on. That is why a folder can
look sparse when it is actually complete: the people are in the second file.

title="following.json / following_1.json … following_N.json"

Every account you currently follow, same shape. Sharded the same way.

If a username appears in both files, that person follows you and you follow them. That is the
whole of it, and it is genuinely all you need to reconstruct the shape of the graph as it
stands today.

Two practical notes before you go further. First, the shards must be concatenated — reading
only followers.json when a followers_1.json also exists gives you a wrong answer with no
error. Second, usernames are matched case-insensitively, because people change the
capitalisation of their handles and an export can capture two snapshots that disagree about it.
We saw to that below; it is a bigger deal than it sounds.

That is the honest headline: the export describes your graph as a present-tense picture. If
someone followed you in 2015 and left in 2021, they appear in neither file. The edge existed
for six years and the folder has no trace of it.

The set arithmetic, and one word that means the opposite of what it sounds like

Here is the entire derivation layer, and it is short enough to hold in your head.

Let F be the set of people who follow you and Y the set you follow. Then:

ViewHow it is producedWhat it means
**Mutuals**F ∩ YYou follow each other
**Fans**F − YThey follow you; you do not follow back
**The reverse**Y − FYou follow them; they do not follow back
**All of it**F ∪ YEveryone in your graph, counted once

That is four lines of set subtraction and it is the most reliable information in your entire
archive. No timestamps, no interpretation, no inference — just two lists and the difference
between them. Everything a tool calls your "social graph summary" is built from this.

The one caveat on all four views: they are only as good as the two files. An export where
connections arrived as HTML rather than JSON can carry fewer names than the same account's
JSON export, which would quietly shrink your mutuals. We have covered that failure at length
in Why your Instagram export is missing half your life,
because it produces confidently wrong counts rather than obvious gaps.

The other twelve lists, and what each one is for

None of these adds a person. Each one is a small view or a private setting, and each is worth
reading for a different reason. The file names have apostrophes and percent-escapes in them —
profiles_you've_favorited.json arrives as several different mangled spellings depending on
the export — which is a large part of why these folders look emptier than they are.

close_friends.json and profiles_you've_favorited.json. The first is your Instagram close-friends
list, which is genuinely curated by hand and is therefore one of the few lists in the whole
export that reflects a real decision. The second is the set of profiles you have favourited.
Neither adds anyone to your graph; both tell you something about your own organisation.

None of these twelve lists is a source of follow edges. They are filters, settings and
leftovers. If someone is in your graph, they are in followers.json or following.json and
nowhere else.

The three derived relations worth reading closely

Set subtraction gets you the shape. Three further derivations get you the parts of the graph
that are genuinely uncomfortable to look at, and they are the reason this folder is worth
opening at all.

title="They unfollowed you, and you still follow them"

recently_unfollowed ∩ followers. The classic asymmetry: you are following an account
that has removed you. It is short, it is recent-bounded, and it is the only place in the
entire export where this shows up. There is no date on it that you can rely on for the moment
the follow ended — the folder is a snapshot of who has recently unfollowed, not a log.

This is the number people want and the number the export is worst at supporting. You can know
that it happened. You cannot know when.

title="They asked to follow you and you never answered"

follow_requests_you've_received − followers. A request that was never accepted, and
which therefore never became a follow edge. Because acceptance is the thing that puts someone
into followers, subtracting it leaves exactly the set of requests that are still sitting
unanswered.

This is the one list where the arithmetic is doing something genuinely kind to you. You cannot
remember requests you ignored, and Instagram does not surface them either. The export does, and
it is the closest thing to a record of a specific kind of inattention.

title="They asked to follow you, you ignored it, and you follow them"

the set above ∩ following. The sting. They reached out, the request was never accepted,
and meanwhile you have been following them. Both halves of that are verifiable from the same
two files, which is exactly why it is uncomfortable and exactly why it is in the folder.

All three are pure set arithmetic over lists Instagram already gave you. None of them is a
model, none of them is a guess, and none of them takes anything off your device.

The request sitting in your pending folder

One detail here is counter-intuitive enough to be worth stating on its own, because it is the
kind of thing that sends people looking for a file that does not exist.

The accounts you have requested to follow are not in your following list. Verified against
real exports: Instagram keeps sent requests in their own pending_follow_requests.json,
entirely separate from following.json. So "who have I asked to follow and not yet been
accepted by" is simply the pending folder — there is no subtraction to perform and no second
file to find. If you have ever gone looking for a person you requested inside your following
list and concluded you must have been blocked, that is the explanation: they are in the pending
folder, waiting.

There is a related trap in the same folder. A request that was accepted can linger as a
record. If a username appears in both your pending folder and followers.json, the honest
reading is that the request succeeded and the record stayed behind — so the pending folder is a
list of requests, not a list of rejections, and it is not necessarily a list of things still
awaiting an answer. Our parser treats the duplicate as accepted rather than as still-pending,
because the follow itself is the stronger evidence.

title="Deleted accounts arrive wearing a placeholder"

Accounts that no longer exist appear in your lists with a username beginning __deleted__.
This is not a bug and not corruption — it is how a removed account is represented, and the
display name is usually the only surviving trace of who it was.

We scan every relation list for this pattern rather than just the two main ones, because a
dead account turns up wherever it was referenced: in followers, in close friends, in favourites,
in the people you unfollowed. The number of them is worth knowing on its own — it is a rough
measure of how much of the graph you are looking at has already decayed.

Casing drift, the quiet way a graph breaks

This one is small and it has bitten real analysis.

Instagram usernames are case-insensitive, and a person can change the capitalisation of their
handle at any time. An export is a snapshot of many files that were written at different
moments, so the same account can appear as SamSmith in one file and samsmith in another.

Compare those as raw strings and you get two people. In a mutual count you get an inflated
number; in an overlap list you get someone who appears to follow you and whom you do not
follow back, which is not a thing. The fix is one line — lowercase and trim every username
before it is used as a key — and we mention it because it is invisible when it goes wrong. A
wrong count looks exactly like a right one.

What is not in here at all

The relationship lists do not add up to who you actually reached. That is a different question about interaction volume, which counts messages, reactions, saves, reels, stories and searches per person rather than current follow ties.

This is the section that decides whether you can trust anything else on this page.

There is one more trap worth naming, because it is the same shape as a bug and it is not a
relationship bug: your totals can legitimately go down between two exports. Instagram's
counts are windowed by the date range and categories you requested, so an export covering
2025–2026 can honestly report fewer posts than one covering 2019–2025. A tool that renders the
smaller number as though content was deleted is misreporting a narrower window as a loss. This
one catches people constantly and it has nothing to do with people unfollowing you.

Four levels of certainty, and why we show them

Here is a small design decision that we think matters more than anything else on this page.

When LMKFR shows a date next to a person, it does not show a date alone. It shows where the
date came from, on a four-level scale:

LabelWhat it means
**From Instagram**Instagram supplied an actual instant, so we can print a day and a time
**Bounded**We can prove the date fell inside a range — from diffing two exports
**First seen**This is when the account appeared in *your* data, which is a fact about your archive, not about the relationship
**Unknown**There is no date. We print nothing

Every surface that renders relationships — the accounts list, the people insights, connection
depth, the public profile — reads from a single shared derivation, so they cannot drift apart
or contradict each other. That is not a styling preference. It is the failure mode that makes
people stop trusting a tool: two screens in the same app giving two different answers about the
same person.

How to read your relationships without lying to yourself

The practical part, now that you know what the folder can and cannot support.

Your mutuals — the intersection is the real graph, and it is the only list here that is both
complete and meaningful. Then fans, because a large asymmetric follower count is a genuine
finding about your account rather than a metric. Then the unfollowed-but-still-following
list, which is the one that reliably produces a conclusion. Finally close_friends.json, which
is the only hand-curated list in the entire export.

And the one habit worth forming: the graph tells you who, the messages tell you who mattered.
The social graph is a diagram of who was connected to you. It has no idea which of those
connections were real, because the format does not store that and no amount of clever reading
recovers it. Every person on that list is on it for the same reason — a button got pressed at
some point — and the interesting difference between a meaningful relationship and a forgotten
one lives somewhere the connections folder cannot see.

Two shapes, one folder, and why a folder can look empty when it is not

The connections folder is not one format. It is three, mixed together, and which one a given
file uses decides whether you find a list in it or nothing at all.

The usual shape is an array of objects, each carrying a string_list_data array with
username and profile_name inside it. Most of the follower and following files look like
this and you will recognise them immediately.

The nested shape is the same thing wearing an extra layer — relationship_list_data
instead, sometimes as the primary key and sometimes tucked alongside. Our reader accepts either
on the same object, because Instagram is not consistent about which one it writes.

The label/value shape is the odd one out, and it is the reason some files appear to contain
nothing at all. Instead of an array of users, the file holds an array of label_values pairs —
a label string and a value string — where the actual username has to be picked out by
matching its label. restricted_profiles.json regularly arrives this way. A tool that only
knows how to read string_list_data will parse that file, find zero users, and report nothing,
which is indistinguishable from the file being absent.

There is a fourth variation that only appears in the HTML variant of the same folder. Rather
than JSON objects, the rows are HTML table or list lines, and the usernames have to be
recovered from links while the surrounding text is checked for a date — a month name, a day, a
year — or for a word like following, followed, mutual or joined to confirm the row is a
person at all. It works, and it is fragile, and it is another reason the JSON export is
preferable whenever you have the choice. The reasoning is in
Why your Instagram export is missing half your life;
the short version is that a recovered-from-HTML list is a best effort, and it should never be
presented with the same confidence as a parsed one.

The number that is a percentage wearing a fraction's clothes

One more engineering detail, because it produced a genuinely absurd bug in our own dashboard and
it is worth using as a worked example of why relationship maths deserves more care than it gets.

The natural stat here is a follow-back rate: of everyone you follow, what proportion follows
you back. Computed correctly that is mutuals / following, multiplied by one hundred, rounded
— a number between 0 and 100, printed as 63.

Compute it and return 0.63, and then render it by multiplying by one hundred again, and you
get 63 displayed as 6300. Which is what happened: a follow-back rate of five thousand
percent, rendered in a large friendly typeface on a public-facing card, driven by an
undefined follower count and a missing guard. The underlying maths was correct the entire
time. Only the unit contract between the function and the view was wrong.

What a careless tool shows

Follow-back rate: 5200%

Fan count: 0 · Unfollowed: 1,204 · Mutual: 3

Everything is a number, every number is large, and nothing on the screen is wrong in a way you
could catch without checking the arithmetic by hand.

What the same data actually supports

Follow-back rate: unknown — no following list in this export

Fan count: — · Unfollowed: — · Mutual: —

The connections folder did not arrive in this archive. The honest render is a dash with a
sentence explaining why, which is less satisfying and is the correct answer.

The lesson generalises past this bug: a unit mismatch between a function and its caller is
invisible until a real number is large enough to be embarrassing.
The defensive fix was to make
the empty case impossible to mistake for a zero — return nothing rather than a number when the
denominator is missing — and to derive that value once, in one place, so no view can invent its
own version of it.

That last point is the one we care about most. Every relationship number in LMKFR comes from a
single shared derivation rather than being recomputed per screen. It is not a performance
choice. It is what stops two pages in the same app from disagreeing about the same person, which
is the fastest way to make someone stop trusting everything else you show them.

Questions this comes up

How do I see who unfollowed me from my export?

Find recently_unfollowed.json in the connections folder. It is a real list and it is the only
place an unfollow shows up — but it is recently unfollowed, so it is bounded and incomplete,
and it will not tell you when. Accounts that are in that folder while also being in your
followers.json are the ones you still follow after they removed you. To catch people who
unfollowed and are not in that folder at all, keep two exports and diff them.

Why does my export say I have fewer posts than last time?

Because Instagram's totals are windowed by the date range and categories you requested. A
2025–2026 export can legitimately report fewer posts than a 2019–2025 one, and nothing was
deleted in between. Request the same full range both times, or treat cross-export total
comparisons as meaningless. This catches people constantly and it looks exactly like data loss.

What is the difference between a follower, a mutual and a fan?

A follower follows you. A mutual is in both followers.json and following.json, so
you follow each other. A fan follows you but is not in your following list. All three are
computed by comparing the two files, and none of the three is stored as its own list.

Can I tell when I first followed someone?

Usually not. The rows that carry relationships mostly have no usable timestamp — many carry a
timestamp of zero, which means absent rather than 1970. Where Instagram does supply an instant
we show it; otherwise we show when the account first appeared in your data and label it as
exactly that, because it is a fact about your archive rather than about the relationship.

Why is my block list empty or missing?

An Instagram export does not reliably include a block list, so the folder is frequently absent
or empty. That is the file being unhelpful, not you misremembering. Message-derived signals like
someone you left on read are a genuinely different measurement and are labelled separately —
collapsing them into a "blocked" count would be inventing a fact about another person.

Someone I requested to follow is not in my following list. Were they blocked?

Almost certainly not. Requests you have sent live in pending_follow_requests.json and are
not part of following.json at all, which is why they look missing. A request that was later
accepted can also leave a record behind in that folder while the person appears normally in
followers.json — we read the duplicate as accepted, since the live follow is the stronger
evidence.

What are these __deleted__ accounts?

Accounts that no longer exist, represented by a placeholder username beginning __deleted__,
with the display name usually surviving as the only trace. We scan every relation list for
them rather than only the two main ones, because deleted accounts turn up wherever they were
referenced. The count is a rough measure of how much of the graph has already decayed.

Why does my follower count sometimes go down between two exports?

It is almost never a mass unfollow. Instagram's counts are windowed by the date range and
categories you requested, so a 2025-2026 export can honestly report fewer of everything than a
2019-2025 one. Relationship lists are also current-value snapshots: a new ZIP overwrites the old
one and nobody reads the previous value again, so a follower who disappeared between downloads
leaves no trace in either file. Request the same full range both times, and treat cross-export
follower-count comparisons as unproven rather than as a loss.

My connections folder is empty. Is that real?

Check which format it arrived in before believing it. If the connections section came as HTML
rather than JSON, or if the files use the label_values shape instead of the usual
string_list_data array, a parser that only understands the common shape will return nothing at
all and the folder will look genuinely empty when it is not. An unrecognised structure and a
truly empty list are indistinguishable in the file itself, which is why a trustworthy tool has
to tell them apart rather than printing the same zero for both.

Where the sourced version lives

Every file name above is one our parser genuinely matches, and the derivations are the ones the
parser actually performs — mutuals as intersection, fans as difference, the three second-order
relations computed from recently_unfollowed and follow_requests_you've_received, dead
accounts scanned across all fifteen lists. The pending-requests detail and the stale-pending
duplicate were verified against real exports rather than assumed.1

The three file shapes described above are the ones the reader actually handles: the
string_list_data array, the relationship_list_data variant, and the label_values pair
form that makes files like restricted_profiles.json look empty to anything expecting only the
first. Meta's download documentation describes the connection files without specifying an
internal shape, so this is observed from real exports across both the JSON and the HTML variant
rather than quoted from a specification.2

The four absences above are not opinions about the format. They are recorded as specific
findings — destructive state, regressing totals, structurally unrecoverable follow dates, and
the date-confidence scale — in our internal ledger plan, which exists because a single-archive
app otherwise shows the one date Instagram happened to include and silently drops the other.
If you want the folder-by-folder version of what arrived, that is
What's actually inside your Instagram data export;
if you want to know why the numbers can disagree with reality, that is
Why your Instagram export is missing half your life.

1: Verified against real exports on 2026-08-22: sent follow requests are kept in
pending_follow_requests.json and are not part of following.json. A pending entry whose
username also appears in followers.json is read as an accepted request with a stale record,
since the live follow edge is the stronger evidence.
2: Meta's Download Your Information help pages describe the connection files without
specifying an internal shape - <https://www.facebook.com/help/1215911857479922>

LMKFR is an independent project. It is not affiliated with, endorsed by, or associated with
Instagram or Meta, and it works only with a file you already hold. Every count described here is
set subtraction over your own lists, computed on your own device — nothing was inferred and
nothing left the browser.

Footnotes

  1. pending
  2. shapes
Who was actually in your Instagram life? — LMKFR Blog