[00:00] (0.08s)
AI coding tools. I'm interested how much
[00:02] (2.16s)
do you use the current ones? What do you
[00:04] (4.40s)
use? What is working? I think Apple's
[00:06] (6.16s)
built-in Xcode one is perfectly fine. I
[00:08] (8.32s)
use it a tremendous amount. Like I feel
[00:10] (10.40s)
like chat GPT has officially replaced my
[00:12] (12.96s)
knowledge of Git. I can never remember
[00:14] (14.80s)
how to use Git invocations properly. So
[00:16] (16.72s)
I just pop open a window and be like,
[00:17] (17.92s)
"Hey, can you please re-educate me on
[00:19] (19.76s)
this?" I use a lot for that kind of like
[00:21] (21.12s)
ad hoc things where I don't have an idea
[00:22] (22.64s)
of where to start. I've noticed that
[00:24] (24.08s)
they are starting to do a lot more when
[00:26] (26.00s)
you ask it a question it can generate a
[00:27] (27.76s)
lot more complicated like it'll give you
[00:29] (29.36s)
a integrated kind of web project or
[00:31] (31.68s)
something like that. I'm excited to look
[00:33] (33.36s)
back into that. But yeah, on the mobile
[00:35] (35.20s)
side I've asked it a couple of specific
[00:37] (37.20s)
wrinkly questions that I actually have
[00:39] (39.28s)
to solve on a day-to-day basis. I've
[00:40] (40.80s)
never once gotten good code for those,
[00:42] (42.32s)
but it's a good rubber duck if you're
[00:43] (43.76s)
trying to like break down a problem and
[00:45] (45.28s)
carve it up into chunks and ask it focus
[00:46] (46.96s)
questions. You might get decent code. So
[00:48] (48.72s)
in personal projects, I've used Gemini's
[00:50] (50.88s)
built-in Android Studio. It's honestly
[00:52] (52.80s)
pretty good. I don't use it to ask
[00:54] (54.24s)
questions and have it write code for me.
[00:55] (55.92s)
Honestly, I still don't believe that
[00:57] (57.36s)
that's going to work very well, but as
[00:59] (59.04s)
like a very fancy, efficient
[01:00] (60.88s)
autocomplete, it's fantastic. Reddit
[01:02] (62.48s)
completely reroll it iOS and Android
[01:04] (64.08s)
apps starting in 2021 and did so without
[01:06] (66.64s)
most of us noticing any of it. But why
[01:09] (69.04s)
did they do it and how? Today, we reveal
[01:11] (71.68s)
details by talking with three members of
[01:13] (73.28s)
Reddit's mobile platform team, Lauren
[01:15] (75.76s)
Darcy, Brandon Kobalinsky, and Eric
[01:18] (78.56s)
We cover the sheer size of Reddit,
[01:22] (82.08s)
how they employ more than 200 mobile
[01:23] (83.84s)
engineers, have around 2 and a half
[01:25] (85.36s)
million lines of code for both iOS and
[01:27] (87.28s)
Android, more than 500 screens, and
[01:29] (89.36s)
hundreds of modules. How Reddit changed
[01:31] (91.84s)
their API from REST to GraphQL, and why
[01:34] (94.16s)
this was more tricky to do than most
[01:35] (95.68s)
assumed it would be. Why Android chose
[01:38] (98.08s)
Jetack Compose when Compose was still in
[01:39] (99.92s)
alpha, and why iOS decided not to use
[01:42] (102.00s)
Swift UI at the time, and why the iOS
[01:44] (104.24s)
team is reversing course now, and many
[01:46] (106.24s)
more details. If you're interested in
[01:48] (108.00s)
how a fully remote mobile engineering
[01:49] (109.44s)
team operates and makes decisions and
[01:51] (111.28s)
want to understand the challenges of
[01:52] (112.64s)
building mobile apps used by tens of
[01:54] (114.16s)
millions of users, this episode is for
[01:56] (116.32s)
you. If you enjoy the show, please
[01:58] (118.00s)
subscribe to the podcast on any podcast
[01:59] (119.60s)
platform and on YouTube. Welcome to the
[02:01] (121.84s)
podcast all of you. Thank you. Thank
[02:04] (124.64s)
you. Happy to be here. So to start off,
[02:06] (126.56s)
can we get a sense of what is the scale
[02:09] (129.12s)
and shape of the Reddit codebase? And
[02:11] (131.36s)
you right now we're talking about the
[02:12] (132.72s)
mobile codebase of course. Uh yeah, I
[02:15] (135.12s)
guess I can start with Android. Um
[02:16] (136.64s)
there's some like standard scale metrics
[02:18] (138.72s)
uh I don't know two and a half or so
[02:20] (140.24s)
million lines of code about 800 modules.
[02:22] (142.88s)
Um but the thing that really surprises
[02:24] (144.72s)
people is we have about 580 screens. Um
[02:29] (149.28s)
you know you you think of Reddit and you
[02:30] (150.72s)
think of like the feed and the post
[02:32] (152.08s)
detail screen. Uh maybe a handful of
[02:33] (153.84s)
others but to this day I do not
[02:36] (156.48s)
understand how we have this many screens
[02:38] (158.32s)
or where they all go but we have a lot.
[02:40] (160.80s)
I don't know Brandon you want to give
[02:42] (162.08s)
the iOS take on that? The iOS site is
[02:44] (164.56s)
actually I think a pretty similar size.
[02:46] (166.00s)
We're behind on having like a more
[02:47] (167.76s)
specific concept of screen that like I
[02:49] (169.36s)
would trust. But my favorite answer to
[02:50] (170.88s)
this question is like we're we're large
[02:53] (173.20s)
enough that if you ask me like what
[02:55] (175.04s)
scale we are, I have to ask you
[02:56] (176.48s)
clarifying questions of like, well, do
[02:58] (178.40s)
you care about generated code? Do you
[02:59] (179.92s)
care about specific kinds of targets?
[03:01] (181.36s)
Because like we've got a thousand basil
[03:03] (183.36s)
targets, but I would have to take 15
[03:04] (184.72s)
minutes to categorize them or ask
[03:06] (186.40s)
Brenley uh uh to figure it out. But
[03:09] (189.28s)
yeah, it's it's big enough that we don't
[03:11] (191.68s)
have to prove that it's too big.
[03:14] (194.24s)
And I guess one one question for this
[03:16] (196.40s)
type size of code bases for those who
[03:18] (198.24s)
are not as familiar with let's say
[03:19] (199.60s)
mobile is the compile time on on back
[03:22] (202.40s)
end and on web it's usually not a big
[03:25] (205.28s)
deal although on typescript it could be
[03:27] (207.20s)
but on mobile usually is you know these
[03:28] (208.96s)
type of code bases a million line plus
[03:30] (210.96s)
often would compile 10 minutes 15
[03:33] (213.04s)
sometimes even longer than that what is
[03:34] (214.96s)
your compile time like from fresh
[03:38] (218.00s)
again I this question causes me to make
[03:40] (220.24s)
a face because if you end up being a
[03:42] (222.16s)
Reddit iOS developer that ends up being
[03:43] (223.84s)
like, hey, my build times, because I
[03:45] (225.20s)
think if you do the entire app,
[03:46] (226.72s)
everything, it's probably about 30
[03:48] (228.56s)
minutes. Um, but that'll cache a bunch
[03:51] (231.04s)
of things and after that it's going to
[03:52] (232.32s)
be way faster. Um, but uh if you are
[03:56] (236.00s)
exposed to a 30-minute build time, we're
[03:59] (239.20s)
probably going to see you on a chart and
[04:00] (240.24s)
be like, "Hi, why are you building the
[04:01] (241.44s)
whole app? Would you like to be more
[04:02] (242.72s)
productive? Can you try a couple of
[04:04] (244.00s)
these different techniques?" Uh, because
[04:05] (245.84s)
it's really hard to make that any
[04:07] (247.36s)
faster.
[04:08] (248.88s)
Yeah. On the Android side, um,
[04:10] (250.56s)
incremental builds are are not bad at
[04:12] (252.40s)
all. I think our clean builds are
[04:14] (254.40s)
somewhere in the neighborhood of 8 to 9
[04:17] (257.00s)
minutes. Um, but that's with, you know,
[04:19] (259.84s)
remote build caching and a lot of things
[04:21] (261.44s)
that we have to to kind of help things
[04:22] (262.72s)
out. Yeah. But, but just to clarify, as
[04:25] (265.52s)
as you said, random as well, you
[04:27] (267.52s)
wouldn't really do a clean build except
[04:29] (269.28s)
maybe on your first day or, you know,
[04:31] (271.44s)
when you join or if you've been away
[04:33] (273.28s)
from, I don't know, a long time or or
[04:35] (275.04s)
you do something. So, it's just a rare
[04:36] (276.40s)
event, right? Like most devs on the
[04:37] (277.84s)
day-to-day, you're going to do like
[04:39] (279.04s)
small incremental builds that we're
[04:40] (280.56s)
talking are not beyond minutes and
[04:42] (282.56s)
probably even faster. Yeah. And
[04:44] (284.16s)
essentially we we try to get people into
[04:46] (286.72s)
uh uh like selected focus targets or
[04:48] (288.88s)
like I think we we have a couple of
[04:50] (290.24s)
names for this because we've had it for
[04:52] (292.16s)
a long time. We've had varying versions
[04:54] (294.64s)
of this tech like our playgrounds. We
[04:56] (296.40s)
want you to take like a selection of
[04:57] (297.76s)
those targets and do like a focus mode.
[04:59] (299.28s)
I think other places call it. Um, and in
[05:01] (301.44s)
those builds like you'll vary from if
[05:03] (303.92s)
you're in the feed area where you have a
[05:06] (306.00s)
tremendous amount of dependencies, maybe
[05:07] (307.60s)
that'll take 10 minutes, but the small
[05:10] (310.16s)
libraries that I might be working on,
[05:11] (311.44s)
it's like 30 seconds to a minute. You
[05:13] (313.60s)
like it doesn't take any time at all. If
[05:15] (315.92s)
you're outside of the main project and
[05:18] (318.56s)
as as context, you mentioned, you know,
[05:20] (320.00s)
number the lines of code, which we know
[05:21] (321.52s)
is not a perfect metric, but above a
[05:23] (323.60s)
certain size, it does give you a sense,
[05:25] (325.12s)
right? Like Uber has a similar size for
[05:27] (327.44s)
example and again a lot of Starbucks
[05:28] (328.88s)
will have a lot lot lot a lot smaller.
[05:31] (331.36s)
What is the size of a team that
[05:33] (333.44s)
maintains uh all of this right all of
[05:35] (335.84s)
Reddit's native apps? It's a great
[05:38] (338.24s)
question. Uh we have two dedicated
[05:40] (340.80s)
platform teams for Android and iOS. Uh
[05:43] (343.76s)
they're about 10 to 11 engineers a piece
[05:47] (347.36s)
on a good day. Uh and they support about
[05:51] (351.04s)
200 mobile engineers across the company
[05:53] (353.60s)
on different teams. Wow. Uh I I want to
[05:56] (356.80s)
say we have about 20 feature teams and
[05:59] (359.52s)
they are set up like a fairly typical
[06:01] (361.84s)
feature team with some Android, some
[06:03] (363.68s)
iOS, some web engineers, maybe some
[06:06] (366.56s)
dedicated backend engineers, uh an EM, a
[06:09] (369.92s)
PM, a part designer, that sort of
[06:12] (372.28s)
situation. Uh but what's special about
[06:14] (374.64s)
the platform teams is they tend to be
[06:16] (376.24s)
homogeneous. So everyone on the iOS
[06:18] (378.88s)
platform team is an iOS developer.
[06:20] (380.80s)
They're all together. Oh wow. Um, so
[06:23] (383.76s)
they develop a little bit more subject
[06:25] (385.20s)
matter expertise to support all of the
[06:28] (388.00s)
feature iOS developers in their spaces.
[06:30] (390.96s)
Yeah. Because at most places the mobile
[06:33] (393.52s)
platform team would have a mix of like
[06:35] (395.28s)
50% Android, 50% iOS. Usually the one
[06:37] (397.92s)
the ones I've seen. Yep. Uh we we work
[06:41] (401.20s)
more like sister teams instead of having
[06:43] (403.44s)
one team that is both platforms. We also
[06:45] (405.92s)
have a web platform team and a UI
[06:48] (408.16s)
platform team that owns the design
[06:49] (409.68s)
system. This episode is brought to you
[06:51] (411.52s)
by Graphite, the developer productivity
[06:53] (413.76s)
platform that helps developers create,
[06:55] (415.68s)
review, and merge smaller code changes,
[06:57] (417.76s)
stay unblocked, and ship
[06:59] (419.72s)
faster. Code review is a huge time sync
[07:02] (422.24s)
for engineering teams. Most developers
[07:04] (424.40s)
spend about a day per week or more
[07:06] (426.00s)
reviewing code or blocked waiting for a
[07:08] (428.20s)
review. It doesn't have to be this way.
[07:11] (431.12s)
Graphite brings stack pull requests, the
[07:13] (433.28s)
workflow at the heart of the
[07:14] (434.24s)
best-in-class internal code review tools
[07:16] (436.00s)
at companies like Meta and Google to
[07:18] (438.00s)
every solver company on
[07:19] (439.64s)
GitHub. Graphite also leverages high
[07:22] (442.16s)
signal codebase aware AI to give
[07:23] (443.92s)
developers immediate actionable feedback
[07:25] (445.60s)
on their poll requests, allowing teams
[07:27] (447.76s)
to cut down on review cycles. Tens of
[07:30] (450.64s)
thousands of developers at top companies
[07:32] (452.40s)
like Asana, Ramp, Tecton, and Verscell
[07:34] (454.72s)
rely on Graphite every day. Start
[07:37] (457.28s)
stacking with graphite today for free
[07:39] (459.20s)
and reduce your time to merge from days
[07:40] (460.96s)
to hours. Get started at
[07:44] (464.12s)
gt.dev/pragmatic. That is g for graphite
[07:48] (468.52s)
technology.dev/pragmatic. This episode
[07:50] (470.08s)
is brought to you by Sentry. Buggy lines
[07:52] (472.88s)
of code and long API calls are
[07:54] (474.32s)
impossible to debug and random app
[07:56] (476.32s)
crashes are things no software engineer
[07:58] (478.00s)
is a fan of. This is why over 4 million
[08:01] (481.28s)
developers use Sentry to fix errors and
[08:03] (483.28s)
crashes and solve hidden or tricky
[08:04] (484.96s)
performance issues.
[08:07] (487.12s)
Centrica's debugging time in half. No
[08:09] (489.76s)
more soul crushing lock sifting or vague
[08:11] (491.84s)
user reports like it broke, fix it. Get
[08:15] (495.20s)
the context you need to know what
[08:16] (496.88s)
happened, when it happened, and the
[08:18] (498.32s)
impact down to the device, browser, and
[08:20] (500.48s)
even a replay of what the user did
[08:22] (502.08s)
before the error. Central will alert the
[08:24] (504.64s)
right dev on your team with the exact
[08:26] (506.24s)
broken line of code so they can push a
[08:28] (508.16s)
fix fast. Or let Autofix handle the
[08:30] (510.64s)
repetitive fixes so your team can focus
[08:32] (512.56s)
on the real problems.
[08:34] (514.88s)
Sentry helpmonday.com reduce their
[08:36] (516.88s)
errors by 60% and sped up time to
[08:39] (519.12s)
resolution for next door by 45 minutes
[08:41] (521.12s)
per dev per issue. Get your whole team
[08:43] (523.84s)
on sentry in seconds by heading to
[08:46] (526.84s)
centry.io/pragmatic. That is s nt r
[08:51] (531.96s)
y.io/pragmatic or use the code pragmatic
[08:54] (534.40s)
on sign up for 3 months on the team plan
[08:56] (536.32s)
and 50,000 errors per month for free. I
[08:59] (539.28s)
I have to ask this question because
[09:00] (540.80s)
people are going to already asking it in
[09:02] (542.32s)
their heads. Why does Reddit have so
[09:04] (544.48s)
many mobile engineers? And by the way, I
[09:06] (546.16s)
we I did get this when I was at Yuber as
[09:08] (548.08s)
well, but and you've you've gotten this
[09:10] (550.16s)
so many times before, right? But again,
[09:12] (552.40s)
Eric, you already mentioned the 580
[09:14] (554.48s)
screens, which some people will just not
[09:16] (556.88s)
really believe, but we we've all
[09:19] (559.12s)
mentioned now more than like 100 mobile
[09:21] (561.36s)
engineers, which is a lot. Like this
[09:22] (562.88s)
this will make you one of the largest
[09:24] (564.88s)
native mobile engineering
[09:28] (568.60s)
organizations globally. pro maybe not
[09:31] (571.12s)
the single biggest one but probably top
[09:32] (572.80s)
10. It's really scary when you say it
[09:35] (575.04s)
that way
[09:37] (577.76s)
in in in one team that is right like you
[09:39] (579.92s)
will have I don't know Google if you if
[09:41] (581.76s)
you add up they'll have a lot more
[09:43] (583.12s)
combined but but not in one app. Yeah.
[09:45] (585.76s)
So so we talked about the screens we
[09:48] (588.24s)
have a lot of feature surfaces. Um, but
[09:51] (591.04s)
there's also a lot of uh mobile
[09:53] (593.68s)
developers working in areas like
[09:56] (596.72s)
building our safety features and
[09:58] (598.96s)
building our eventing and our logging
[10:01] (601.36s)
and our experimentation platform. Um, so
[10:06] (606.56s)
not everyone is focused on like and our
[10:09] (609.44s)
ads platform also is an entire organ to
[10:11] (611.68s)
itself. Um, so while a lot of the bigger
[10:16] (616.00s)
teams are teams like the feed and the
[10:18] (618.00s)
post detail experience, the things that
[10:20] (620.00s)
many Redditors know and love about
[10:22] (622.44s)
Reddit, there are there's an entire team
[10:25] (625.04s)
just devoted to supporting mods. Um, so
[10:29] (629.44s)
when once you get into all of the
[10:31] (631.28s)
different sorts of areas plus an entire
[10:33] (633.52s)
dev platform that is trying to extend
[10:35] (635.92s)
the experience to third party developers
[10:37] (637.84s)
to actually build on Reddit, um, it gets
[10:41] (641.84s)
big fast. The other big investment we
[10:44] (644.56s)
saw, I want to say like a year and a
[10:46] (646.72s)
half to two years ago, is we have a lot
[10:50] (650.84s)
uh, we we don't call them estats, but we
[10:53] (653.92s)
actually have a lot more automation
[10:55] (655.20s)
folks. So a good portion of our actual
[10:58] (658.16s)
builds are being are part of our test
[11:00] (660.56s)
infra investment. Um which a couple
[11:04] (664.56s)
years ago we didn't have much test infra
[11:06] (666.32s)
and now we have a wide variety of test
[11:08] (668.92s)
infra. Um so they account for quite a
[11:12] (672.24s)
few of the builds that we see running
[11:13] (673.76s)
today too. And then but by test infra
[11:16] (676.00s)
and automation is this end to end test
[11:18] (678.64s)
integration test some some fancy AI
[11:21] (681.60s)
stuff like what what what kind of mix?
[11:23] (683.12s)
I'm assuming it's going to be a mix
[11:24] (684.40s)
right? I I was about to say yes until
[11:26] (686.16s)
you added the AI part. Uh Brandon, Eric,
[11:29] (689.60s)
you want to talk about the different
[11:30] (690.40s)
kinds of tests we have in our test
[11:31] (691.76s)
pyramid? I guess the other part of this
[11:33] (693.84s)
is we did have some hackathon projects
[11:36] (696.00s)
that did some AI testing stuff. They're
[11:37] (697.52s)
just not something we use in tooling a
[11:38] (698.96s)
lot. Um but yeah, testing wise, we have
[11:41] (701.84s)
actually I I think we pulled metrics for
[11:44] (704.40s)
what our code coverage is, but basically
[11:46] (706.32s)
we uh uh ratchet to enforce like um unit
[11:49] (709.44s)
test coverage in various areas. We have
[11:51] (711.52s)
definitely a lot of integration tests
[11:53] (713.12s)
and we also use a lot of
[11:55] (715.84s)
um E2 stuff or like blackbox tech
[11:58] (718.08s)
blackbox testing for like access
[12:01] (721.40s)
accessibility assertions and that kind
[12:03] (723.36s)
of stuff. There's a lot that we actually
[12:04] (724.96s)
do with it. We also do weird stuff like
[12:06] (726.48s)
I've been working for a while on using
[12:09] (729.68s)
the UI testing infrastructure to like
[12:11] (731.36s)
exercise the app and then try to connect
[12:12] (732.96s)
it to leaks to do memory leak analysis
[12:15] (735.20s)
inside of our endto-end testing. Um, so
[12:18] (738.40s)
yes, the answer to your question is we
[12:20] (740.08s)
have all of those in a pretty good mix.
[12:22] (742.24s)
And is this simulators or do you
[12:23] (743.92s)
actually have a device lab where like
[12:25] (745.52s)
these the things are deployed and and
[12:28] (748.24s)
you're holding your hat so probably I
[12:30] (750.16s)
completely well yeah I completely forgot
[12:31] (751.68s)
that we also have uh we partner with a
[12:34] (754.00s)
vendor to do that as well. Yes. So every
[12:36] (756.48s)
kind of test I think it we've come a
[12:38] (758.72s)
long way. uh when I joined I we didn't
[12:41] (761.52s)
have coverage metrics uh but I want to
[12:44] (764.08s)
say we're like maybe 2% unit test
[12:46] (766.56s)
coverage um and nothing beyond that. Um,
[12:50] (770.24s)
so this is something that's like really
[12:51] (771.92s)
grown within the last, I don't know,
[12:53] (773.84s)
two, three years. Um, where I think our
[12:56] (776.64s)
our testing story is quite a bit better
[12:58] (778.96s)
than it used to be, but I think we still
[13:00] (780.56s)
have a long ways to go, honestly. Um, I
[13:02] (782.72s)
think we have the pyramid established,
[13:05] (785.12s)
but actually kind of filling in all the
[13:06] (786.80s)
bricks on the pyramid has some ways to
[13:08] (788.48s)
go. And like you've done way more
[13:10] (790.48s)
testing than most engineering teams will
[13:12] (792.16s)
do, and especially, you know, startups
[13:13] (793.44s)
starting out will not even dream of
[13:15] (795.04s)
doing. So what has been the the benefit?
[13:17] (797.76s)
You know, you put in a bunch of work,
[13:18] (798.96s)
right? Like cuz I I do hear engineers
[13:21] (801.92s)
asking like why bother, right? Like it's
[13:24] (804.32s)
it's going to be a lot of effort.
[13:25] (805.60s)
They're hard to maintain. We know end to
[13:27] (807.20s)
end tests especially on mobile are are
[13:28] (808.96s)
slow, etc. What have you gotten out of
[13:32] (812.08s)
this? So I if we go back a couple years
[13:35] (815.92s)
like Eric was saying, we had almost 0%
[13:38] (818.48s)
test coverage and we were having a lot
[13:40] (820.72s)
of incidents in prod that were easily
[13:44] (824.08s)
preventable.
[13:45] (825.88s)
Um, and so there was a whole shift left
[13:50] (830.24s)
approach of trying to find those things
[13:52] (832.08s)
before our users were telling us about
[13:53] (833.84s)
them at scale. Um, and so I think that
[13:57] (837.92s)
our test info became a part of that. But
[14:00] (840.40s)
it was actually really hard to stand up
[14:01] (841.92s)
in the first place and that was because
[14:04] (844.00s)
we were in a tech debt situation that
[14:06] (846.72s)
had really really long build times with
[14:09] (849.20s)
no test infra in place yet. So we didn't
[14:13] (853.12s)
have a lot of capacity that we could
[14:14] (854.64s)
say, hey, we're willing to increase our
[14:16] (856.32s)
build times to add tests in to be more
[14:20] (860.20s)
protective. So uh you have a kind of
[14:24] (864.24s)
perfect storm of rapid growth in our
[14:26] (866.40s)
engineering orgs. So lots more people
[14:28] (868.16s)
running builds. our builds are already
[14:30] (870.48s)
really really long and we want to
[14:32] (872.32s)
introduce all this test coverage and
[14:33] (873.92s)
we're constantly having incidents with
[14:35] (875.60s)
the fact that we don't have test
[14:36] (876.88s)
coverage in place and we were mostly
[14:39] (879.76s)
relying on manual QA from an overseas uh
[14:42] (882.72s)
vendor with like a 12-hour turnaround.
[14:45] (885.04s)
So fixing things ouch really really
[14:47] (887.48s)
difficult. Uh so I think trunkbased
[14:50] (890.16s)
development so shifting where we're
[14:51] (891.60s)
testing and what artifacts we're
[14:53] (893.80s)
testing introducing automation ideally
[14:57] (897.04s)
in places that we felt had value first.
[14:59] (899.44s)
So if you're in a postmortem and you
[15:01] (901.92s)
notice that a test could have resolved
[15:04] (904.56s)
this in a way that uh we would never
[15:06] (906.32s)
have this problem again. Those are the
[15:07] (907.84s)
tests that we really tried to evangelize
[15:10] (910.68s)
first. Tests like that issue or similar
[15:14] (914.80s)
to that issue. um it's a lot easier to
[15:17] (917.68s)
convince people those are tests that
[15:19] (919.12s)
pull their weight and are worth
[15:21] (921.16s)
running. Um but yeah, we did have
[15:23] (923.76s)
ratchets in place to just kind of
[15:25] (925.36s)
increase testing across the board and a
[15:29] (929.04s)
lot of those kind of contracting firms
[15:30] (930.96s)
we brought in to actually help us build
[15:32] (932.72s)
tests and build a like culture of
[15:36] (936.08s)
testing. And I will say though that the
[15:38] (938.72s)
the downsides you brought up are very
[15:40] (940.72s)
real. Uh we've had lots of issues with
[15:42] (942.72s)
flaky tests. you know, people, like I
[15:44] (944.72s)
said, we started with virtually no
[15:46] (946.24s)
coverage. And so now all these engineers
[15:48] (948.56s)
who maybe have never written a test in
[15:50] (950.40s)
their life. Um are now trying to test
[15:52] (952.24s)
their code that was not written to be
[15:54] (954.00s)
very testable. Um so we we ended up with
[15:57] (957.44s)
a lot of bad tests and a lot of flaky
[15:59] (959.12s)
tests and a lot of pain around it. Um so
[16:01] (961.44s)
it is very real. Yeah. I tech that
[16:04] (964.64s)
exists anywhere regardless of whether
[16:06] (966.08s)
it's in your app or your test code. One
[16:08] (968.00s)
of the thing or one of the uh little
[16:10] (970.72s)
tidbits that was really helpful to me is
[16:12] (972.16s)
we had someone who uh joined Reddit
[16:14] (974.64s)
after we had kind of go gone through
[16:16] (976.08s)
this process and we were talking about
[16:17] (977.60s)
some of our frustrations with the
[16:18] (978.72s)
testing and he's like this is the first
[16:20] (980.56s)
place I've worked at that like added a
[16:23] (983.04s)
ratchet and like it worked like yes we
[16:25] (985.76s)
have flaky tests. If you have tests
[16:27] (987.20s)
you'll always have some flick in there.
[16:28] (988.24s)
That will just be true. But like you
[16:30] (990.00s)
also have mobile yeah you also have a
[16:32] (992.80s)
lot of tests. And when Eric was
[16:34] (994.40s)
referring to like some of these iffy
[16:36] (996.48s)
tests, one of my favorite like side
[16:38] (998.00s)
effects of trying to build tests is
[16:39] (999.44s)
you're at least adding code paths to
[16:42] (1002.00s)
like inject your dependencies and like
[16:43] (1003.52s)
you can at least reach that code in test
[16:45] (1005.68s)
which means even if you can write a bad
[16:46] (1006.96s)
one today, you can probably write a good
[16:48] (1008.48s)
one tomorrow much simpler than starting
[16:50] (1010.56s)
from zero. There's a there side effects
[16:52] (1012.96s)
have absolutely been worth it.
[16:55] (1015.84s)
So you you're doing a lot of modern
[16:57] (1017.52s)
engineering practices. One of the things
[16:59] (1019.44s)
that is the most modern and you know
[17:00] (1020.88s)
maybe the future. So some some you know
[17:02] (1022.64s)
there's a lot of hype around it is AI
[17:04] (1024.32s)
coding tools. I'm interested how much do
[17:06] (1026.88s)
you use the current ones? What do you
[17:09] (1029.20s)
use? What is working or or how much did
[17:11] (1031.44s)
it help you or even if it helps you? And
[17:12] (1032.96s)
I'm asking this because especially with
[17:14] (1034.56s)
native mobile you know this these tools
[17:16] (1036.72s)
are not nearly as cutting edge as does
[17:18] (1038.32s)
as they are let's say on web or or or
[17:21] (1041.04s)
some of the the kind of JavaScript
[17:22] (1042.64s)
frameworks. I'm just interested in like
[17:24] (1044.48s)
like today, you know, like like just
[17:25] (1045.84s)
honestly like like what are you getting
[17:27] (1047.52s)
out of it and and what is working? What
[17:29] (1049.28s)
is uh not really working?
[17:33] (1053.60s)
YouTube, this is a little bit of a
[17:34] (1054.88s)
tricky one to answer. Um so in personal
[17:38] (1058.32s)
projects I've used, you know, Gemini is
[17:40] (1060.00s)
built in Android Studio. It's honestly
[17:42] (1062.08s)
pretty good. I don't you I don't use it
[17:43] (1063.68s)
to ask questions and have it write code
[17:45] (1065.44s)
for me. Honestly, I still don't believe
[17:47] (1067.44s)
that that's going to work very well. Um,
[17:49] (1069.68s)
but as like a very fancy, efficient
[17:52] (1072.00s)
autocomplete, it's fantastic. Yeah, I
[17:54] (1074.40s)
think Apple's built-in Xcode one is is
[17:56] (1076.48s)
perfectly fine. I use it a tremendous
[17:58] (1078.24s)
amount. Like I feel like chat GPT has
[18:00] (1080.96s)
officially replaced like my knowledge of
[18:02] (1082.96s)
git. I can never remember how to use git
[18:05] (1085.20s)
like invocations properly. So I just pop
[18:07] (1087.20s)
open a window and be like, "Hey, can you
[18:08] (1088.64s)
please re-educate me on this?" Um, I use
[18:11] (1091.36s)
a lot for that kind of like ad hoc
[18:12] (1092.80s)
things where I don't have an idea of
[18:14] (1094.00s)
where to start. Um, I've noticed that
[18:16] (1096.32s)
they are starting to do a lot more like
[18:18] (1098.72s)
when you ask it a question, it can
[18:20] (1100.24s)
generate a lot more complicated like
[18:21] (1101.84s)
it'll give you a integrated kind of web
[18:24] (1104.72s)
project or something like that. Um, I'm
[18:27] (1107.60s)
excited to look back into that. But
[18:29] (1109.28s)
yeah, on the mobile side, I've asked it
[18:31] (1111.20s)
a couple of like specific wrinkly
[18:33] (1113.68s)
questions that I actually have to solve
[18:35] (1115.52s)
on a day-to-day basis. I've never once
[18:37] (1117.36s)
gotten good code for those, but it it's
[18:39] (1119.44s)
a good rubber duck if you're trying to
[18:40] (1120.72s)
like break down a problem and and carve
[18:43] (1123.12s)
it up into chunks and ask it focus
[18:44] (1124.64s)
questions. You might get decent code.
[18:46] (1126.00s)
You're always always going to have to
[18:47] (1127.20s)
revisit it. But yeah, I think most of
[18:49] (1129.44s)
just the personal project bug standard
[18:51] (1131.52s)
ones. I I I do wonder if these tools
[18:54] (1134.88s)
we'll see a similar thing with uh what
[18:57] (1137.36s)
we're seeing with native mobile
[18:58] (1138.40s)
development. You know, native mobile
[18:59] (1139.44s)
development tooling is different than
[19:01] (1141.44s)
than web than backend. we've always had,
[19:04] (1144.88s)
you know, if you iOS, I mean, you're
[19:06] (1146.88s)
doing it right. Xcode has has different
[19:08] (1148.56s)
functionality. Android Studio or or Jet
[19:11] (1151.04s)
Brains ID has and the challenges are
[19:13] (1153.76s)
just different. So, I I feel there what
[19:16] (1156.32s)
what we might see, you know, certain
[19:17] (1157.76s)
teams using it on other domains might
[19:19] (1159.68s)
work better and, you know, maybe mobile
[19:21] (1161.36s)
either catch up or be slower or who
[19:23] (1163.36s)
knows, maybe it's a different fit.
[19:26] (1166.24s)
I I think we are using it in a couple of
[19:29] (1169.12s)
ways though. So, so I agree with Eric
[19:31] (1171.84s)
that rapid prototyping with the Android
[19:34] (1174.72s)
Studio Gemini features are pretty cool.
[19:36] (1176.56s)
That is a lot of fun to do on the side
[19:38] (1178.08s)
and for validating ideas before you
[19:40] (1180.40s)
actually make them official Reddit
[19:41] (1181.92s)
ideas. So, is is it fair for me to
[19:44] (1184.32s)
rephrase that you know for AI coding
[19:46] (1186.00s)
tools specifically for mobile it
[19:48] (1188.16s)
somewhat useful like you know some
[19:49] (1189.68s)
people use it here and there but sounds
[19:51] (1191.52s)
like the bigger use case is you actually
[19:53] (1193.84s)
using this technology LLMs and elsewhere
[19:56] (1196.88s)
to add to your to your workflows. you
[19:59] (1199.84s)
know, and eventually maybe even your dev
[20:02] (1202.24s)
tools, but sounds like that's kind of a
[20:03] (1203.92s)
little bit more more promising and
[20:05] (1205.12s)
exciting path. Did I sense this right?
[20:07] (1207.12s)
Yeah, I think that's right. I think our
[20:08] (1208.88s)
test insights are also somewhat powered
[20:11] (1211.44s)
by AI now, but we're not really using
[20:13] (1213.20s)
them as much as we could. Um, I would
[20:16] (1216.40s)
love to see them more like we had a lot
[20:19] (1219.92s)
of investment in test infrastructure,
[20:22] (1222.16s)
but there's a lot of duplication in it.
[20:24] (1224.32s)
And when a team goes and looks at how
[20:27] (1227.04s)
many tests they actually need and how
[20:28] (1228.72s)
many are P zeros, it's usually a very
[20:30] (1230.48s)
small subset of what is currently
[20:32] (1232.16s)
sitting there. Um, being able to
[20:34] (1234.72s)
actually figure out what tests are
[20:36] (1236.32s)
pulling their weight post Ratchet is a
[20:40] (1240.16s)
great place I think that we might see AI
[20:42] (1242.40s)
in use. Yeah.
[20:45] (1245.16s)
And let's talk about the the interesting
[20:48] (1248.80s)
topic that we wanted to talk about. you
[20:50] (1250.48s)
did a really big tech mobile
[20:52] (1252.88s)
modernization starting from maybe 2021.
[20:55] (1255.28s)
Can you tell me what was the state? Why
[20:58] (1258.16s)
did you decide to suddenly make make a
[20:59] (1259.84s)
big change which as I understood also
[21:01] (1261.52s)
led to hiring more more native uh
[21:03] (1263.56s)
engineers and how did it go?
[21:06] (1266.96s)
Uh it that's a big topic for us that we
[21:09] (1269.04s)
really like to talk about. Um let's see
[21:12] (1272.16s)
uh let me try and set the stage. So, uh,
[21:16] (1276.28s)
2021, um, Reddit is, uh, growing as a
[21:20] (1280.68s)
company. They are trying to establish
[21:24] (1284.24s)
themselves more as an international
[21:26] (1286.08s)
company instead of a US domestic
[21:28] (1288.68s)
company. Um, and uh, they're seeing the
[21:34] (1294.00s)
world shift from a like web- based space
[21:37] (1297.44s)
to a mobile based space, especially
[21:39] (1299.60s)
overseas.
[21:41] (1301.36s)
uh that led to a whole bunch of new
[21:43] (1303.36s)
strategy which led to a whole bunch of
[21:45] (1305.92s)
hiring across many many teams especially
[21:48] (1308.48s)
in the mobile space.
[21:51] (1311.08s)
Um and so we start seeing a a team that
[21:55] (1315.92s)
was probably in the like 40 engineers 50
[22:00] (1320.00s)
engineers across both platform size and
[22:03] (1323.36s)
within like two years were around 200.
[22:07] (1327.52s)
Uh and that is the space in which
[22:12] (1332.16s)
uh you start from a place of having
[22:14] (1334.56s)
really really poor build times like two
[22:16] (1336.56s)
and a half hours type of a thing with no
[22:19] (1339.28s)
test infrastructure but all of these big
[22:22] (1342.36s)
goals. Um and it's also around that time
[22:26] (1346.16s)
that platform teams really started to
[22:27] (1347.92s)
form officially. Brandon, you can
[22:29] (1349.68s)
correct me if I'm wrong here. It was
[22:31] (1351.04s)
within that year or so where we kind of
[22:33] (1353.44s)
transitioned from a company like many
[22:35] (1355.52s)
companies that kind of beg and borrow
[22:37] (1357.84s)
platform support from everybody to keep
[22:40] (1360.96s)
things up and going to saying we need
[22:42] (1362.72s)
proper platform teams that are going to
[22:44] (1364.56s)
actually help us scale this way.
[22:47] (1367.44s)
I think that time frame is about right.
[22:49] (1369.36s)
Oh no, actually that that's definitely
[22:50] (1370.96s)
right because I was like I this is my
[22:53] (1373.20s)
brief dip as an EM in this thing and I
[22:55] (1375.04s)
got to hire a couple people. Um, but we
[22:57] (1377.28s)
were kind of, at least from my
[22:58] (1378.64s)
perspective on iOS, we had always been
[23:00] (1380.48s)
about three people supporting however
[23:02] (1382.24s)
big the org was. So like the iOS
[23:04] (1384.32s)
platform team was three from the time
[23:05] (1385.84s)
that we had 10 or 15 engineers until
[23:09] (1389.84s)
until about the time frame Lori is
[23:11] (1391.28s)
describing. And yeah, it was uh it was a
[23:15] (1395.20s)
lot. It was a tremendous amount of work.
[23:16] (1396.96s)
I can remember specific incidents about
[23:19] (1399.12s)
this, but yeah, it was really a time
[23:21] (1401.04s)
where we could finally start developing
[23:22] (1402.80s)
at least the start of like specific
[23:24] (1404.96s)
areas of expertise instead of uh uh
[23:27] (1407.68s)
platform engineers just being experts in
[23:29] (1409.44s)
everything and then having to pretend
[23:30] (1410.88s)
that it wasn't stressful and context
[23:33] (1413.28s)
switchy. So, so one of the things that
[23:35] (1415.92s)
happened though is we're hiring all this
[23:38] (1418.08s)
great talent because we really want to
[23:39] (1419.92s)
invest in mobile and they're showing up
[23:43] (1423.28s)
and onboarding is rough. They have never
[23:46] (1426.48s)
seen build times anything like this. If
[23:49] (1429.20s)
you ask them what the tech stack is,
[23:50] (1430.96s)
we're like, "What team are you joining?"
[23:52] (1432.48s)
It depends on what team you're joining.
[23:53] (1433.84s)
And then we'll tell you what your tech
[23:55] (1435.12s)
stack is, maybe if there is one. Um, and
[24:00] (1440.00s)
uh, so we're getting a ton of feedback
[24:01] (1441.52s)
from our existing developers and the new
[24:03] (1443.92s)
people showing up that Debex is not
[24:07] (1447.36s)
bringing them any joy.
[24:09] (1449.76s)
feature teams have these big ambitious
[24:12] (1452.16s)
new goals and the feature team uh hiring
[24:15] (1455.76s)
like they they join together they form a
[24:17] (1457.44s)
team and they can't execute because our
[24:20] (1460.40s)
codebase is really slow and they can't
[24:22] (1462.72s)
figure out how to how to actually like
[24:25] (1465.04s)
deploy safely. All of the things are
[24:27] (1467.84s)
kind of coming up at once. Um, yep.
[24:31] (1471.20s)
Yeah, I was gonna say one of my favorite
[24:33] (1473.76s)
um, actually least favorite I guess uh,
[24:35] (1475.52s)
stories about this was when I joined.
[24:37] (1477.60s)
Um, so I guess I'll say I'm generally
[24:39] (1479.76s)
all for people on any team uh, getting
[24:42] (1482.00s)
to know you know the finer points of
[24:43] (1483.36s)
their tooling and their tech stack. Uh,
[24:45] (1485.20s)
but there's one fact I strongly believe
[24:47] (1487.28s)
that not a single feature engineer
[24:48] (1488.88s)
should ever know and that is at what
[24:51] (1491.04s)
point their CI provider decides that
[24:53] (1493.04s)
it's more likely that a process is stuck
[24:54] (1494.80s)
in an infinite loop than that you're
[24:56] (1496.56s)
actually still trying to build. Uh but
[24:59] (1499.12s)
when I joined we weren't so lucky. Um I
[25:01] (1501.12s)
regularly had to retry PRs after they
[25:03] (1503.52s)
get timed out on CI after you know two
[25:05] (1505.12s)
and a half hours. Um and you know like a
[25:07] (1507.92s)
lot of these were from decisions that
[25:09] (1509.04s)
made a lot of sense when we were small
[25:10] (1510.40s)
team small code base and we just didn't
[25:13] (1513.36s)
have the the staffing to readress them
[25:16] (1516.16s)
as we grew. Um so yeah we we kind of
[25:19] (1519.44s)
reached a point where something had to
[25:21] (1521.76s)
be done. So it wasn't just Devx though.
[25:24] (1524.64s)
This was also bleeding out into the
[25:26] (1526.24s)
users and their experience. So, uh this
[25:29] (1529.76s)
is around the time where we probably had
[25:31] (1531.52s)
our all-time worst stats on mobile um
[25:34] (1534.88s)
across both platforms. In terms of
[25:37] (1537.60s)
ratings or or feedback, all of the
[25:40] (1540.24s)
above. Uh I started in in 2021 and the
[25:44] (1544.24s)
week I started
[25:45] (1545.80s)
our our Android startup time was 13
[25:49] (1549.68s)
seconds at P90. Uh I think Brendan our
[25:53] (1553.44s)
iOS was around 7 to 8 seconds P90. It
[25:56] (1556.56s)
was the worst of before Bolt. Um
[26:00] (1560.56s)
uh we I I was pulled out of my
[26:03] (1563.04s)
onboarding the first week for a feed
[26:04] (1564.64s)
incident that had no observability. We
[26:06] (1566.64s)
couldn't figure out what was going on
[26:08] (1568.32s)
even that we were not showing
[26:10] (1570.76s)
feeds. Um so we we were basically blind
[26:15] (1575.12s)
to the problems that we had. We were
[26:16] (1576.64s)
just constantly reacting to problems at
[26:18] (1578.56s)
that point.
[26:20] (1580.28s)
Uh, and so I think that that all of this
[26:24] (1584.36s)
together became a really good like pivot
[26:28] (1588.88s)
point for the company to say these are
[26:31] (1591.28s)
all becoming really big liabilities for
[26:33] (1593.12s)
us. We need to actually have a plan uh
[26:35] (1595.60s)
uh for how we're going to resolve our
[26:37] (1597.52s)
Devex issues so that we can actually
[26:40] (1600.08s)
build what we want to build. but also to
[26:42] (1602.24s)
dig ourselves out of the hole that we
[26:43] (1603.68s)
were in from a from a like existing tech
[26:47] (1607.92s)
perspective. It needed to be a like
[26:50] (1610.08s)
pretty comprehensive
[26:53] (1613.24s)
Um so that kind of sets the stage for
[26:56] (1616.32s)
how we bring together a group of people
[26:59] (1619.12s)
to define our tech stack and where we go
[27:01] (1621.20s)
from there. And then what was your
[27:04] (1624.08s)
journey in the modernization? So what
[27:06] (1626.32s)
what were the the things that you put in
[27:07] (1627.92s)
place? We previously me talked about
[27:10] (1630.32s)
before the recording about a monorreo
[27:12] (1632.56s)
which is an interesting one. Early on
[27:14] (1634.80s)
executive leadership asked us for a
[27:17] (1637.64s)
prescription for what was going to be
[27:20] (1640.08s)
our kind of like big solve and ideally
[27:22] (1642.80s)
could we have a kind of umbrella effort
[27:25] (1645.52s)
that that kind of trademarked the entire
[27:27] (1647.88s)
approach and that's how we ended up with
[27:30] (1650.16s)
a branded name for our tech stack which
[27:32] (1652.00s)
is core stack. So this is for the new
[27:34] (1654.80s)
stack right? Yes. This is this is our
[27:36] (1656.64s)
answer to
[27:37] (1657.72s)
everything. Um and I'll very quickly
[27:42] (1662.64s)
TLDDR it. Uh at the bottom of it, it is
[27:46] (1666.88s)
how are we going to organize our code?
[27:48] (1668.80s)
We we agree that we are going to
[27:50] (1670.56s)
organize it in a monor repo for each
[27:53] (1673.88s)
platform modularized primarily by
[27:57] (1677.04s)
feature.
[27:58] (1678.80s)
Y uh above that we're going to use a
[28:02] (1682.56s)
modern programming language. we're going
[28:04] (1684.16s)
to commit to using the modern program
[28:07] (1687.12s)
programming language for the given
[28:09] (1689.32s)
platform. Uh we were already
[28:13] (1693.44s)
uh one thing that was helpful was that a
[28:15] (1695.44s)
lot of these particular choices were
[28:17] (1697.52s)
already well underway. They just needed
[28:19] (1699.36s)
to be blessed and pushed into the like
[28:21] (1701.44s)
primary way we wanted people to work
[28:23] (1703.52s)
which made it actually pretty easy to go
[28:25] (1705.12s)
down most for most of these choices. Um
[28:28] (1708.96s)
but uh we were in the middle of a
[28:30] (1710.56s)
GraphQL transition from a REST company.
[28:32] (1712.96s)
So we committed to being a GraphQL first
[28:35] (1715.52s)
client and then a GraphQL only
[28:37] (1717.88s)
client. Um above that we see a little
[28:40] (1720.96s)
bit of divergence across the two uh
[28:43] (1723.40s)
platforms but we settled on MVVM of some
[28:48] (1728.20s)
flavor. Do you want to explain why we
[28:51] (1731.20s)
chose MVVM Eric Brendan?
[28:56] (1736.20s)
Uh sure. Um I mean a lot of it was kind
[28:59] (1739.76s)
of forced by we haven't talked about
[29:01] (1741.60s)
this yet but our UI our UI framework
[29:03] (1743.68s)
choice of compose um so we were
[29:06] (1746.16s)
previously an MVP model view presenter
[29:09] (1749.20s)
uh architecture pattern which was even
[29:11] (1751.28s)
when I joined felt very out ofd and a
[29:13] (1753.60s)
little odd um but it was fine right like
[29:16] (1756.24s)
it's it's better to have consistency
[29:18] (1758.88s)
than to have a few things here and a few
[29:20] (1760.96s)
things there so we we just kept going
[29:22] (1762.56s)
with it um despite it not really being
[29:24] (1764.56s)
anyone's favorite um But the issue was
[29:27] (1767.84s)
kind of forced when we chose Jetack
[29:29] (1769.52s)
compose because it is a reactive
[29:31] (1771.12s)
framework. So we can no longer use
[29:33] (1773.12s)
imperative architecture patterns to
[29:34] (1774.88s)
drive a reactive framework. So we kind
[29:36] (1776.24s)
of had to um settle on something else
[29:38] (1778.84s)
which you know uh the the industry has
[29:42] (1782.24s)
more or less settled on MVVM or MVI or
[29:44] (1784.96s)
some flavor of that. Um so and so sorry
[29:48] (1788.96s)
just for those who who don't know so
[29:50] (1790.32s)
MVVM model V view model right and MVP
[29:53] (1793.12s)
model view presenter. Yes. Yes correct.
[29:56] (1796.32s)
And what is the difference between the
[29:57] (1797.76s)
the the two, right? They sound pretty
[29:59] (1799.60s)
similar. You have the model, you have
[30:01] (1801.04s)
the view, and then you have a third
[30:02] (1802.32s)
thing, but they're different. Yeah. So,
[30:05] (1805.12s)
the really what it boils down to is
[30:07] (1807.28s)
imperative or reactive. Um there there
[30:09] (1809.84s)
are several other differences, but that
[30:11] (1811.60s)
was the main driver for us. Um using a a
[30:14] (1814.48s)
reactive UI framework, we were kind of
[30:16] (1816.40s)
forced to stop using imperative uh logic
[30:18] (1818.72s)
to drive it.
[30:20] (1820.80s)
Brandon, how about the iOS side? we have
[30:22] (1822.88s)
a so iOS uh that this was a little bit
[30:26] (1826.32s)
more complicated. So we at that point we
[30:28] (1828.32s)
were evaluating Swift UI and kind of
[30:30] (1830.40s)
like where we were at. I think our back
[30:31] (1831.76s)
deployment version on that was still iOS
[30:34] (1834.24s)
14. So Swift UI was I think technically
[30:36] (1836.40s)
possible. I can never remember when it
[30:37] (1837.68s)
was actually 13 at the time. Oh. But uh
[30:40] (1840.56s)
Swift UI introduced some problems from
[30:42] (1842.16s)
that perspective. And it also was just
[30:43] (1843.68s)
like it was still pretty new cuz we're
[30:46] (1846.16s)
talking about 21. It was three years old
[30:47] (1847.84s)
at that point and it it's still a little
[30:50] (1850.16s)
still pretty fresh. Um, so we opted for
[30:52] (1852.80s)
a layer on top of basically collection
[30:55] (1855.68s)
view we called slice kit. I'm pretty
[30:57] (1857.20s)
sure we've had some blog posts about
[30:58] (1858.64s)
this. I can't remember exactly. We
[31:00] (1860.64s)
talked about that uh uh for a while. It
[31:02] (1862.80s)
had a lot of benefits like there there's
[31:04] (1864.48s)
some cool things that if you kind of if
[31:06] (1866.48s)
you imagine uh wrapping a screen in a
[31:09] (1869.44s)
collection view behind the scenes,
[31:11] (1871.04s)
there's some really nice things like
[31:12] (1872.16s)
dynamic type was trivial to just like
[31:14] (1874.64s)
get that stuff working. Um, I think
[31:16] (1876.48s)
Conrad's pretty happy with how
[31:17] (1877.92s)
accessibility can work uh in some of
[31:20] (1880.32s)
those areas. Um, but ultimately we
[31:23] (1883.04s)
started running into issues because
[31:24] (1884.64s)
writing a declarative wrapper around UI
[31:27] (1887.20s)
kit is tremendously complicated. And it
[31:29] (1889.92s)
turns out even Apple uh is, you know,
[31:32] (1892.16s)
not perfect at doing it. Swift UI, I
[31:33] (1893.92s)
would argue, is what we wanted at that
[31:35] (1895.76s)
point, at least from the the code we
[31:38] (1898.00s)
wanted to write wasn't just quite ready
[31:39] (1899.76s)
yet. So, we're revisiting some of that,
[31:41] (1901.60s)
but I think we'll talk about that in a
[31:42] (1902.88s)
little bit. Yeah, it was a it was a
[31:44] (1904.72s)
pretty legit journey though. Yeah. So,
[31:47] (1907.84s)
we choose MVVM for both of our platforms
[31:51] (1911.36s)
with a slightly different answer for
[31:53] (1913.76s)
what our UI framework is going to be. We
[31:56] (1916.00s)
choose compose on the Android side. We
[31:58] (1918.08s)
choose Slicekit on the iOS side. One is
[32:00] (1920.56s)
an industry standard and one is an
[32:03] (1923.04s)
internal
[32:04] (1924.76s)
uh choice let's say. Yeah. Uh, and then
[32:08] (1928.16s)
on top of that, we build our new design
[32:09] (1929.96s)
system. Um, which is ideally going to
[32:13] (1933.68s)
solve for a lot of the feature delivery
[32:16] (1936.48s)
pain around people con like constantly
[32:19] (1939.60s)
reinventing the wheel. Um, I think that
[32:22] (1942.16s)
at one point there were like 15 spinner
[32:24] (1944.96s)
controls in each client and there was a
[32:27] (1947.36s)
guy on Reddit that just like
[32:28] (1948.56s)
continuously found new ones and posted
[32:30] (1950.88s)
about them. Uh, I love that guy.
[32:33] (1953.64s)
Um but yes, so it wasn't particularly uh
[32:38] (1958.04s)
revolutionary except in small parts. A
[32:41] (1961.28s)
lot of it had already been started but
[32:43] (1963.28s)
and committed to but some of these
[32:44] (1964.72s)
projects had been going for like 3 to 6
[32:47] (1967.92s)
years already and not finishing which
[32:50] (1970.32s)
had left us in a place of
[32:53] (1973.08s)
uh the worst of both worlds. When I got
[32:56] (1976.80s)
here, if you had an incident, um, our
[33:00] (1980.24s)
client was half planted in the old REST
[33:03] (1983.04s)
world and half planted in the new
[33:05] (1985.12s)
GraphQL world, and you had to know which
[33:08] (1988.40s)
team and which project and which
[33:10] (1990.40s)
endpoint you were talking about before
[33:11] (1991.92s)
you could solve for even where to look
[33:13] (1993.84s)
at the observability for that element.
[33:17] (1997.64s)
Um, and so, uh, you could vastly reduce,
[33:22] (2002.32s)
um, and simplify for everyone. Then a
[33:24] (2004.88s)
lot of things would get easy. And our
[33:27] (2007.28s)
promise wait our promise uh for core
[33:29] (2009.92s)
stack was if you actually followed our
[33:31] (2011.36s)
our simple prescription platform teams
[33:34] (2014.08s)
would be here to build easy mode tools
[33:37] (2017.76s)
to provide golden paths and to generally
[33:40] (2020.72s)
make it easy for feature teams to focus
[33:43] (2023.04s)
on building the best features instead of
[33:44] (2024.96s)
struggling with the tools and the
[33:47] (2027.12s)
architecture.
[33:49] (2029.36s)
So starting from the bottom uh in terms
[33:51] (2031.76s)
of the the API you mentioned there was
[33:53] (2033.84s)
there was a transition from REST to
[33:56] (2036.28s)
GraphQL why did it happen and what did
[33:58] (2038.72s)
that mean for for the mobile clients
[34:00] (2040.40s)
especially that you know as we know for
[34:02] (2042.72s)
native mobile you can't just like ship a
[34:04] (2044.80s)
new version and forget about the the old
[34:06] (2046.64s)
versions you you either need to have
[34:08] (2048.32s)
backward support or you need to have
[34:10] (2050.16s)
some sort of kill switch which forces
[34:12] (2052.08s)
you to update you know WhatsApp is I
[34:14] (2054.16s)
think for people using it they they will
[34:16] (2056.16s)
say saying oh this this version of the
[34:17] (2057.92s)
app cannot be used. You need to download
[34:20] (2060.08s)
a new one. But uh until until things
[34:22] (2062.00s)
like that are built, you can't really do
[34:23] (2063.68s)
that. So like what what what was the
[34:25] (2065.12s)
impact and you know how long did that
[34:27] (2067.20s)
take and how do you how do you respond?
[34:30] (2070.72s)
Oh my gosh. I I it would be funny if I
[34:33] (2073.68s)
actually did the math on how long it
[34:35] (2075.20s)
took. Like I think right now it's true
[34:37] (2077.52s)
that we're not in an active GraphQL
[34:39] (2079.28s)
migration, but for most years of me
[34:41] (2081.12s)
being at Reddit, there's been some kind
[34:42] (2082.48s)
of of that migration. like the
[34:45] (2085.72s)
uh we were tackling it early on. Um one
[34:49] (2089.36s)
of the shout outs to uh Aiden who was in
[34:52] (2092.16s)
charge of our like original iOS GraphQL
[34:54] (2094.16s)
implementation is like that system is
[34:56] (2096.32s)
actually still in the codebase today. So
[34:58] (2098.08s)
we got 5 years out of that thing at
[35:00] (2100.08s)
least. Um but it provided a lot of just
[35:03] (2103.76s)
benefits in terms of contracts and like
[35:06] (2106.96s)
knowing what the mobile app is actually
[35:09] (2109.52s)
doing and which like which client is
[35:11] (2111.84s)
even doing a request. One of the happy
[35:13] (2113.20s)
accidents I actually like is that
[35:15] (2115.04s)
because we have to name our GraphQL
[35:16] (2116.56s)
requests in a specific way. Um there are
[35:19] (2119.20s)
a couple of incidents that got solved in
[35:20] (2120.80s)
15 minutes because we were like, "Oh
[35:22] (2122.16s)
wait, well that call is only deployed on
[35:24] (2124.56s)
Android." So this is an Android specific
[35:26] (2126.00s)
issue. So the like max thing is here. So
[35:28] (2128.72s)
like iOS on call people, you can take
[35:30] (2130.88s)
off like we don't have to worry about
[35:32] (2132.08s)
this. But it was
[35:34] (2134.20s)
a it was a lot. Um but a lot of cool
[35:38] (2138.00s)
benefits. We and we got to build like
[35:40] (2140.08s)
sort of our own Apollo internally. Uh
[35:42] (2142.48s)
that uh finally proved to me that we
[35:44] (2144.48s)
definitely should just use Apollo
[35:45] (2145.76s)
instead of trying to roll our own. It
[35:46] (2146.96s)
turns out it's a complicated thing to
[35:49] (2149.56s)
build. And then then just just to hammer
[35:52] (2152.56s)
home the difference between REST and
[35:53] (2153.96s)
GraphQL. REST is it's it's it's APIs and
[35:57] (2157.28s)
then JSON, right? And then you need to
[35:58] (2158.80s)
do all your validation. With with
[36:00] (2160.44s)
GraphQL, you you get more more type
[36:03] (2163.20s)
safety. Do you? Yeah. Like Oh,
[36:05] (2165.36s)
definitely. So the nice thing is you can
[36:07] (2167.44s)
go and read the GraphQL spec. It is
[36:09] (2169.20s)
actually like this somewhere on the
[36:10] (2170.56s)
internet. I actually had to read that a
[36:11] (2171.76s)
couple weeks ago. Yeah, there's an
[36:13] (2173.04s)
explicit contract. You're going to get
[36:14] (2174.40s)
types. Um there's going to be a schema
[36:16] (2176.08s)
that enforces those types. Um and if you
[36:19] (2179.76s)
think about a older website like uh
[36:22] (2182.24s)
Reddit, you can still probably find some
[36:23] (2183.92s)
of our old school like API
[36:25] (2185.88s)
documentation. A lot of those endpoints
[36:28] (2188.32s)
are like older than some of the people
[36:30] (2190.24s)
who listen to this podcast. like Reddit
[36:33] (2193.28s)
is 20 some years old and there Eric kind
[36:35] (2195.44s)
of alluded to this before. There were a
[36:37] (2197.12s)
bunch of reasonable decisions that were
[36:38] (2198.96s)
made when we like shipped those like
[36:41] (2201.04s)
after 10 years some of those contracts
[36:43] (2203.60s)
have to be reworked. So GraphQL was a
[36:45] (2205.44s)
great opportunity to like apply a layer
[36:47] (2207.52s)
on top of our like old services that
[36:50] (2210.24s)
established a clear contract and like
[36:52] (2212.08s)
allowed people to actually understand
[36:54] (2214.16s)
what clients want and what you know the
[36:56] (2216.32s)
backend needs to surface. I would never
[36:58] (2218.72s)
go back. Go ahead, Eric. I will say
[37:00] (2220.64s)
though like um I I think we took a
[37:03] (2223.12s)
little bit of a naive approach. We
[37:04] (2224.32s)
definitely have some learnings out of
[37:05] (2225.52s)
the migration. Um really what we did at
[37:08] (2228.72s)
least to start out was we took our REST
[37:10] (2230.96s)
API and did a 1:1 migration to GraphQL
[37:14] (2234.40s)
which is not how GraphQL is supposed to
[37:16] (2236.16s)
work, right? Like we take these very
[37:18] (2238.16s)
flat models um and we pull them over to
[37:22] (2242.72s)
GraphQL and then we we don't get that
[37:24] (2244.72s)
type safety really. We get some
[37:26] (2246.16s)
nullability safety but that's about it.
[37:28] (2248.16s)
Um, so we still ended up with just
[37:30] (2250.48s)
massive amounts of client side logic
[37:32] (2252.48s)
that didn't belong there. And we still
[37:34] (2254.88s)
have a lot of these um these issues
[37:37] (2257.20s)
today around too much logic in the app
[37:39] (2259.20s)
or things having to be redesigned in
[37:41] (2261.20s)
kind of weird ways or even just
[37:43] (2263.60s)
overfetching. Some a lot of times we we
[37:46] (2266.24s)
fetch massive amounts of data that we
[37:48] (2268.72s)
never even touch just because it was in
[37:50] (2270.56s)
the REST API so we probably need it. Um,
[37:54] (2274.56s)
so we made some mistakes. we have some
[37:56] (2276.72s)
learnings and you know it's the kind of
[37:57] (2277.84s)
thing we're still improving every day.
[37:59] (2279.44s)
And then for for this a API migration,
[38:02] (2282.32s)
you know, the API, the back end API
[38:03] (2283.68s)
changing from REST to GraphQL, how did
[38:05] (2285.84s)
it go in terms of like was it the mobile
[38:07] (2287.60s)
teams telling the backend teams, hey,
[38:09] (2289.68s)
this is what we need. This is what the
[38:11] (2291.20s)
app uses. And obviously there's a web
[38:13] (2293.20s)
team as well. Or was it more the other
[38:14] (2294.56s)
way around where the backend team is
[38:15] (2295.76s)
like, okay, we're exposing this things.
[38:17] (2297.76s)
Here's what you're getting. because it's
[38:19] (2299.12s)
always a question kind of who's who's
[38:20] (2300.72s)
leading in terms of you know you have
[38:22] (2302.16s)
the the the teams who are closer to the
[38:24] (2304.48s)
users but there's also the backend teams
[38:26] (2306.40s)
which have a lot of considerations for
[38:28] (2308.56s)
performance functionality
[38:30] (2310.00s)
maintainability that kind of stuff
[38:32] (2312.72s)
that's one of my favorite things about
[38:34] (2314.48s)
GraphQL actually is as long as you have
[38:37] (2317.36s)
some amount of collaboration you can
[38:39] (2319.52s)
usually come up with something that both
[38:40] (2320.88s)
people are happy about um or both sides
[38:42] (2322.88s)
are happy about I guess um you can I
[38:45] (2325.76s)
mean you you have a query and you can
[38:47] (2327.68s)
query only for the very specific fields
[38:50] (2330.00s)
you need and you can kind of form them
[38:52] (2332.08s)
into the data models the way you like
[38:53] (2333.92s)
them. Um, so I it the direct answer to
[38:57] (2337.60s)
your question is it depends on what team
[38:59] (2339.04s)
you're on. Sometimes the backend
[39:00] (2340.80s)
developers are leading it, sometimes the
[39:02] (2342.16s)
client side are, sometimes there's a lot
[39:03] (2343.84s)
of collaboration, but usually both sides
[39:07] (2347.04s)
can be happy just due to the flexibility
[39:09] (2349.12s)
of GraphQL. I think I think initially
[39:12] (2352.00s)
the migration like the web team probably
[39:14] (2354.32s)
started it. Um, but I I feel like they
[39:17] (2357.76s)
pretty immediately pulled in like
[39:19] (2359.68s)
platform people at least. I'm sure Aiden
[39:21] (2361.36s)
was in there like immediately as soon as
[39:22] (2362.80s)
Alex had the idea. Like, so I think it
[39:25] (2365.52s)
started from there, but it pretty
[39:26] (2366.56s)
quickly like we were we were uh in the
[39:28] (2368.48s)
room being able to ask questions and
[39:29] (2369.92s)
provide feedback. For sure. Go ahead,
[39:31] (2371.28s)
Lori. Oh, I was actually going to take a
[39:33] (2373.04s)
different answer on this one. I my
[39:35] (2375.44s)
entire experience at Reddit has been
[39:37] (2377.12s)
around a back-end GraphQL team having
[39:40] (2380.24s)
been established and really helping
[39:42] (2382.48s)
drive the migration away from REST and
[39:44] (2384.64s)
our old infrastructure to a GraphQL and
[39:48] (2388.00s)
then a federated GraphQL model that they
[39:50] (2390.64s)
have been evangelizing and like they've
[39:52] (2392.96s)
been excellent partners to the client
[39:54] (2394.56s)
teams but uh they have definitely driven
[39:57] (2397.20s)
a lot of that adoption and helped us
[40:01] (2401.08s)
like build our actual GraphQL well
[40:04] (2404.16s)
experience
[40:06] (2406.16s)
uh as as client engineers. And some of
[40:09] (2409.44s)
that is because when we go out into the
[40:11] (2411.12s)
the wider talent pool, most people come
[40:13] (2413.76s)
in the door at Reddit not knowing
[40:15] (2415.76s)
GraphQL up front. That has changed over
[40:17] (2417.84s)
time, but it was a lot more unusual in
[40:20] (2420.72s)
the time that we were growing. Most
[40:22] (2422.80s)
people came in with a REST background.
[40:24] (2424.48s)
They had maybe even written a Reddit app
[40:26] (2426.40s)
themselves before they joined the
[40:28] (2428.08s)
company.
[40:29] (2429.24s)
Um, and so, so I think that like our
[40:32] (2432.64s)
journey here involves us learning how to
[40:35] (2435.68s)
write idiomatic GraphQL over time,
[40:39] (2439.12s)
learning what happens when you don't.
[40:42] (2442.20s)
Um, and uh, one of the other things I
[40:45] (2445.20s)
think that
[40:46] (2446.28s)
uh, had an impact on this particular
[40:48] (2448.72s)
project is our initial GraphQL
[40:51] (2451.36s)
implementation was slower than our old
[40:53] (2453.52s)
REST infrastructure. Oh. uh it had a
[40:57] (2457.12s)
latency tax at the like we got the
[41:00] (2460.40s)
flexibility and all the good parts we
[41:01] (2461.92s)
wanted but we had to take it with a a
[41:04] (2464.32s)
latency tax up front for a while. Uh and
[41:08] (2468.16s)
so when we transitioned the the main
[41:10] (2470.56s)
Reddit clients to GraphQL
[41:13] (2473.12s)
um they were noticeably slower on the
[41:15] (2475.68s)
same features we had been running on our
[41:17] (2477.04s)
REST infrastructure before. and we had
[41:19] (2479.20s)
to decide if that was a trade-off we
[41:20] (2480.64s)
wanted to lean into and commit to or uh
[41:23] (2483.68s)
and work through or if we were going to
[41:25] (2485.36s)
rethink our approach. Um ultimately we
[41:27] (2487.92s)
took longer to actually move over to our
[41:29] (2489.84s)
GraphQL infrastructure because we worked
[41:32] (2492.40s)
with the GraphQL backend team to reduce
[41:35] (2495.28s)
that latency and basically make it uh
[41:38] (2498.64s)
much more performant. And so by the time
[41:41] (2501.20s)
our clients moved over, it was in a much
[41:43] (2503.20s)
better place. Uh but there was a point
[41:45] (2505.52s)
in time where it was frustrating for
[41:46] (2506.88s)
feature teams to be migrating in the
[41:49] (2509.52s)
direction of uh with a latency hit. Um
[41:52] (2512.64s)
especially when we were really sensitive
[41:54] (2514.00s)
to to our app being slower for users at
[41:57] (2517.20s)
the time.
[41:59] (2519.04s)
Yeah, this is the the that migration. Uh
[42:01] (2521.60s)
there's a comic about migrations at
[42:03] (2523.28s)
Google. Uh Manukornet the who drew it.
[42:07] (2527.08s)
Uh it it's it's like there's two paths
[42:09] (2529.84s)
to the systems. there's a path that
[42:11] (2531.84s)
doesn't that doesn't work and the one
[42:13] (2533.52s)
that's being deprecated and it's the
[42:15] (2535.44s)
usual store and he he's got a request to
[42:17] (2537.44s)
like whenever he went to like translate
[42:19] (2539.20s)
it because it's usually what happens
[42:20] (2540.16s)
with migrations, right? Nope. But but I
[42:22] (2542.48s)
asked both Brandon and Eric last week if
[42:24] (2544.72s)
they uh feel like GraphQL was the right
[42:27] (2547.76s)
solution for our size at the time. And
[42:30] (2550.88s)
what did you say? I don't know if it was
[42:32] (2552.80s)
the right size of the time, but I I feel
[42:34] (2554.08s)
like this is such a great example of
[42:35] (2555.60s)
like a one of my favorite things about
[42:37] (2557.36s)
Reddit and b why you should just hire
[42:39] (2559.52s)
tech experts and like let them cook is
[42:41] (2561.60s)
like yes, it was slower at the initial
[42:43] (2563.92s)
time, but now like because we have that,
[42:46] (2566.64s)
we can do a bunch of codegen. We can try
[42:48] (2568.56s)
to solve like a bunch of different tech
[42:50] (2570.08s)
problems and there's a bunch of
[42:51] (2571.52s)
optimizations that we can do because we
[42:53] (2573.44s)
have one thing. Uh we only have one kind
[42:56] (2576.08s)
of like networking layer to maintain.
[42:59] (2579.76s)
Well, that's probably not true. We
[43:01] (2581.12s)
probably have too many still, but at
[43:02] (2582.80s)
least we can optimize the GraphQL one.
[43:04] (2584.80s)
But because we, you know, took that or
[43:07] (2587.12s)
made that bet early and let people
[43:09] (2589.04s)
figure out how to make it more
[43:10] (2590.08s)
performant, I'm pretty happy with it.
[43:12] (2592.08s)
I'd do it again. Yeah. Nice. And then
[43:15] (2595.60s)
how did the architecture choices play
[43:17] (2597.92s)
out? So, you mentioned that on on iOS,
[43:20] (2600.64s)
you decided to go with an in-house uh UI
[43:23] (2603.52s)
framework at first. Where where how did
[43:25] (2605.76s)
that work out and where are you right
[43:28] (2608.44s)
um as as ever we are in a period of
[43:31] (2611.04s)
transition. So I I would still say that
[43:34] (2614.24s)
well actually no I would I would fight
[43:36] (2616.16s)
somebody about it. It was absolutely
[43:37] (2617.68s)
worth it for one very big reason like a
[43:40] (2620.32s)
big chunk of the actually let's talk
[43:42] (2622.96s)
about a few things. uh one the feed code
[43:46] (2626.24s)
uh uh in our iOS app is like a very very
[43:48] (2628.80s)
central component and it spreads its
[43:51] (2631.60s)
sort of uh design choices I think pretty
[43:55] (2635.68s)
so the feed code the feed is when you
[43:57] (2637.28s)
open it you see your feed or like feed
[43:59] (2639.68s)
of different Reddits right or different
[44:01] (2641.28s)
subreddits when you think about either
[44:03] (2643.36s)
uh just popping open the app and seeing
[44:04] (2644.80s)
what we would call your home feed like
[44:06] (2646.16s)
the automatically like the automatically
[44:08] (2648.24s)
populated list of posts that we think
[44:10] (2650.16s)
you're you're really going to like that
[44:12] (2652.08s)
infrastructure is actually shared
[44:13] (2653.68s)
between well a lot of it is shared
[44:15] (2655.68s)
between actually the subreddit feed if
[44:17] (2657.04s)
you look at a specific community and
[44:19] (2659.08s)
historically there was a pretty sort of
[44:21] (2661.76s)
nasty uh cluster of of like type
[44:25] (2665.76s)
hierarchies in profiles as well.
[44:28] (2668.00s)
Basically anything where you would show
[44:29] (2669.44s)
a vertical scrolling list of posts is
[44:31] (2671.52s)
probably the same infrastructure. uh
[44:33] (2673.36s)
before this that was based in texture
[44:35] (2675.92s)
and if you're listening to this you
[44:37] (2677.44s)
probably don't remember that framework
[44:39] (2679.12s)
or uh uh what it was but it was uh
[44:41] (2681.84s)
something Facebook started and then
[44:43] (2683.12s)
Pinterest uh shepherded for a long time
[44:45] (2685.60s)
that allowed you to do asynchronous and
[44:47] (2687.52s)
multi-threaded UI.
[44:49] (2689.40s)
So that created a tremendous number of
[44:51] (2691.92s)
complexity if you were like remembering
[44:54] (2694.32s)
Lor's examples of like somebody who
[44:56] (2696.00s)
comes in who doesn't know a particular
[44:58] (2698.32s)
kind of like pattern at Reddit. Nobody
[45:00] (2700.72s)
who we onboarded knew texture. So, uh,
[45:03] (2703.68s)
we wanted to get out of that. The first
[45:05] (2705.52s)
commitment to SliceKit was a massive win
[45:07] (2707.36s)
in that we just are back in Apple's nice
[45:09] (2709.76s)
main thread UI land. Um, however, we ran
[45:13] (2713.36s)
into a lot of issues where it's really
[45:15] (2715.20s)
hard to reuse the components. Uh,
[45:17] (2717.44s)
there's some boilerplate that we just
[45:19] (2719.04s)
can't quite crack. So our what we've
[45:23] (2723.04s)
been working on for a while and how
[45:24] (2724.72s)
we've been kind of going about this is I
[45:27] (2727.52s)
really strongly believe that if you're
[45:29] (2729.04s)
building infrastructure the new thing
[45:31] (2731.44s)
should at least be able to be hosted in
[45:33] (2733.36s)
the old thing. So what we're doing is
[45:35] (2735.12s)
we're saying hey if you're using slice
[45:36] (2736.88s)
kit we're going to figure out ways that
[45:38] (2738.80s)
you can put individual swift UI based
[45:40] (2740.64s)
cells in there and maybe you can
[45:43] (2743.04s)
experime and you can easily AB test on
[45:45] (2745.20s)
those individual cells so you can figure
[45:47] (2747.04s)
out is it performant like is it
[45:49] (2749.20s)
accessible like does it meet all of your
[45:50] (2750.56s)
needs um and you can kind of roll out at
[45:52] (2752.40s)
your own pace and then we're
[45:54] (2754.60s)
essentially adapting that principle so
[45:57] (2757.04s)
that um if you imagine like our vertical
[45:59] (2759.04s)
breakdown of course stack we are
[46:00] (2760.96s)
replacing eventually slice kit with
[46:03] (2763.52s)
swift Swift UI as we prove out areas of
[46:05] (2765.76s)
this thing and uh make sure that it for
[46:08] (2768.24s)
example SwiftUI list is a little bit
[46:10] (2770.64s)
perf suspect right now because it's
[46:12] (2772.32s)
really complicated but uh essentially
[46:15] (2775.00s)
we're replacing it on a manyear time
[46:17] (2777.36s)
scale but we're doing that by making
[46:18] (2778.64s)
sure that the teams who are currently
[46:20] (2780.16s)
leveraging it have support for
[46:21] (2781.76s)
everything that they shipped in prod
[46:22] (2782.96s)
today.
[46:24] (2784.56s)
Smart. I think one of the interesting
[46:26] (2786.56s)
things about this is that when we gave
[46:28] (2788.56s)
our kind of core stack prescription
[46:31] (2791.68s)
uh a lot of us intended for it to be uh
[46:35] (2795.76s)
a starting place that we could make uh
[46:38] (2798.64s)
on once you separate the concerns out a
[46:40] (2800.32s)
bit and you have an established pattern,
[46:42] (2802.72s)
we can build a road map away from that
[46:44] (2804.40s)
pattern if we decide that there's
[46:45] (2805.76s)
something better out there. But a lot of
[46:47] (2807.84s)
people kind of took it as oh when we
[46:49] (2809.84s)
have introduced all the new stuff we'll
[46:51] (2811.68s)
be good forever and we will never have
[46:54] (2814.24s)
to change our minds. But a lot of the
[46:56] (2816.72s)
people who were trying to uh evangelize
[46:59] (2819.76s)
and build out this idea were trying to
[47:02] (2822.56s)
plan for change for the long term
[47:04] (2824.16s)
because we knew that any anything that
[47:06] (2826.32s)
we chose in the past we chose with a
[47:08] (2828.44s)
reason. We had reached a point where
[47:10] (2830.64s)
those particular choices were not
[47:12] (2832.64s)
holding up over time and we needed to
[47:14] (2834.24s)
change them. But we understood that we
[47:16] (2836.96s)
probably would be having the same
[47:18] (2838.16s)
conversations ideally 3 to 5 years later
[47:21] (2841.44s)
about whatever we were doing now. So uh
[47:25] (2845.36s)
Slicekit and Compose were bets on both
[47:28] (2848.28s)
sides. Um they had different uh like
[47:31] (2851.76s)
risk profiles associated with them.
[47:35] (2855.16s)
Um but we wanted to reserve the right to
[47:38] (2858.72s)
not have a like oneway door there where
[47:40] (2860.48s)
we couldn't change our minds later. And
[47:42] (2862.88s)
even the slicekit choice had to like
[47:45] (2865.24s)
intentionally revisit this choice on a
[47:47] (2867.76s)
regular basis
[47:49] (2869.84s)
um for the proper time to consider Swift
[47:52] (2872.44s)
UI. Uh and then how did it work on an
[47:56] (2876.00s)
Android? Because you you took a bet on
[47:57] (2877.60s)
Compose and just like Swift UI, Compose
[47:59] (2879.92s)
back in 2021 was pretty new. Like right
[48:02] (2882.08s)
now everyone it's it's pretty accepted.
[48:04] (2884.64s)
Uh it's it's it's a great way to build
[48:06] (2886.48s)
things. In fact, I'm not even sure
[48:07] (2887.84s)
there's really a competition of how to
[48:09] (2889.60s)
structure like a moderately. But back
[48:11] (2891.52s)
then, this was not the case. It was like
[48:12] (2892.96s)
here's a new new framework. You know, we
[48:16] (2896.64s)
think it'll be good, but you don't know.
[48:19] (2899.76s)
So, so I want Eric to answer this
[48:22] (2902.00s)
question, but one thing I want to to
[48:23] (2903.68s)
preface it with is when things
[48:26] (2906.84s)
are quite bad, you have a lot more
[48:30] (2910.08s)
opportunity to just take bigger bets and
[48:33] (2913.12s)
get away with them if they pay off. So,
[48:36] (2916.56s)
Eric, why did we take the bet on Compose
[48:38] (2918.64s)
as early as we did given how big? Yeah,
[48:41] (2921.36s)
I I don't know how proud of this we
[48:43] (2923.20s)
should be. Probably not super proud. Um,
[48:46] (2926.00s)
but when we started working uh on our
[48:48] (2928.40s)
first compose feature, it was still in
[48:49] (2929.76s)
alpha. We shipped while it was still in
[48:51] (2931.52s)
beta. Wow. Um, yeah. Uh, the reason we
[48:54] (2934.88s)
were able to do this, like Lorie said,
[48:56] (2936.24s)
was that we knew we needed change and
[48:59] (2939.68s)
this looked like the next big thing. At
[49:02] (2942.16s)
the time I was still on a feature team
[49:03] (2943.68s)
and I was working on a brand new feature
[49:05] (2945.52s)
like completely green
[49:07] (2947.08s)
field. Perfect fit for trying something
[49:10] (2950.24s)
brand new. Um you know so I took a bet.
[49:12] (2952.88s)
I I built the whole thing in compose. Uh
[49:14] (2954.96s)
I used MVVM instead of MVP. Um kind of
[49:18] (2958.16s)
introduced a whole lot of new patterns
[49:19] (2959.92s)
that seemed like the way to go. And the
[49:22] (2962.88s)
reason that I was comfortable doing this
[49:25] (2965.12s)
was because I was also willing to go
[49:28] (2968.00s)
back and rewrite it if the bet didn't
[49:29] (2969.92s)
pay out. Um, you know, I was I was the
[49:32] (2972.48s)
sole developer on this feature. I
[49:33] (2973.92s)
completely owned it. I if if it didn't
[49:36] (2976.24s)
work out, if it was a terrible decision,
[49:37] (2977.84s)
I was willing to own that and, you know,
[49:39] (2979.44s)
make it right. Um, and then ju just to
[49:41] (2981.36s)
confirm because yeah, I think what
[49:43] (2983.04s)
people might miss is like Reddit, you
[49:44] (2984.32s)
know, like it's it's a massive app like
[49:46] (2986.64s)
large amount of users are using it. This
[49:48] (2988.56s)
is not just like your, you know, your
[49:50] (2990.24s)
startup with 100 users. And this feature
[49:52] (2992.72s)
that you did, was it like, so it was
[49:54] (2994.40s)
like a nice to have feature or not
[49:56] (2996.56s)
something critical or it was critical,
[49:58] (2998.00s)
but you were just like, okay, I'm going
[49:59] (2999.36s)
to make it work.
[50:00] (3000.88s)
It was I wouldn't call it critical. Um
[50:03] (3003.76s)
so it's it's now gone but it was called
[50:05] (3005.68s)
Reddit talk. Um I don't know how many
[50:07] (3007.52s)
people are familiar with that but it was
[50:08] (3008.96s)
the like live chat room like voice chat
[50:12] (3012.72s)
uh feature club right? Yes. Exactly.
[50:16] (3016.16s)
Yes. Everyone was copying that for a
[50:17] (3017.84s)
while. Um so yeah though it was just
[50:20] (3020.48s)
kind of the perfect opportunity. So it
[50:22] (3022.00s)
it wasn't
[50:23] (3023.24s)
uh it it was it was launched to a very
[50:26] (3026.00s)
small audience. I think it was only like
[50:27] (3027.44s)
two subreddits had the feature at first
[50:29] (3029.36s)
and then we were, you know, slowly
[50:30] (3030.96s)
scaling it as we proved it out. Um, so
[50:34] (3034.00s)
it it wasn't a super risky bet, but
[50:37] (3037.28s)
there was some risk there. Yeah. Well,
[50:39] (3039.60s)
reputation, right? Still, it still only
[50:42] (3042.08s)
took like less than a month to adapt
[50:45] (3045.12s)
talk as it first came about into the
[50:48] (3048.80s)
golden example of what we ultimately
[50:50] (3050.80s)
decided was our very fairly
[50:54] (3054.88s)
straightforward set of tech stack
[50:56] (3056.60s)
choices. And so, uh, it was easy to
[50:59] (3059.28s)
adapt. So, it basically proved out that
[51:01] (3061.52s)
green field work as a starting point for
[51:03] (3063.60s)
our our, uh, new prescription was going
[51:06] (3066.32s)
to work just fine.
[51:08] (3068.68s)
um adapting some of our more legacy
[51:12] (3072.40s)
code, our larger critical path
[51:15] (3075.88s)
features came with like they needed more
[51:18] (3078.64s)
than even our core stack prescription
[51:20] (3080.48s)
was going to give. So they extended it
[51:22] (3082.32s)
in all sorts of interesting ways.
[51:25] (3085.52s)
Now, one thing that you mentioned that
[51:27] (3087.20s)
you're doing, which is very interesting
[51:28] (3088.48s)
to hear, server driven UI, and this is
[51:30] (3090.64s)
interesting because we we talked about
[51:32] (3092.56s)
this with Lori, but a lot of companies
[51:34] (3094.64s)
above a certain size, especially when
[51:36] (3096.48s)
there's native mobile, they they will
[51:39] (3099.04s)
come up with something that might feel
[51:41] (3101.28s)
familiar to, let's say, either React
[51:43] (3103.04s)
Native or or or or just some something
[51:45] (3105.04s)
else with the goal of, you know, being
[51:47] (3107.04s)
able to drive some of the the UI with
[51:48] (3108.88s)
backend changes. What was your approach
[51:51] (3111.28s)
here? Why did you do it? How did you
[51:53] (3113.04s)
build it? And how do you feel about it?
[51:54] (3114.96s)
So while it's not an official part of
[51:57] (3117.36s)
our core stack, we definitely part of
[51:59] (3119.36s)
the core stack idea is that people can
[52:01] (3121.68s)
extend or experiment with anything they
[52:03] (3123.92s)
think is going to work well on their
[52:05] (3125.76s)
surfaces because they're not all the
[52:07] (3127.28s)
same. We have massive feed surfaces and
[52:10] (3130.16s)
we have chat surfaces and they and we
[52:12] (3132.40s)
have profiles and they all really need
[52:14] (3134.80s)
different levels of like complexity and
[52:18] (3138.40s)
uh capabilities. So we definitely had
[52:20] (3140.16s)
some teams try out server-driven UI. Uh,
[52:23] (3143.12s)
I think Brandon, you might have a good
[52:25] (3145.44s)
example where it worked out well. Yeah,
[52:28] (3148.08s)
I think for a lot of those tremendously
[52:29] (3149.84s)
complicated, but one of the things that
[52:31] (3151.20s)
I think has been shipped for a real long
[52:32] (3152.64s)
time is our reporter flow has a like our
[52:35] (3155.12s)
content reporting. if you find something
[52:36] (3156.80s)
that you don't think should be on Reddit
[52:38] (3158.40s)
and you want to report it. Um, there's I
[52:40] (3160.72s)
would say that has some server driven UI
[52:42] (3162.64s)
in it, but since you're like driving
[52:44] (3164.32s)
reporting reasons where you're really
[52:45] (3165.68s)
just trying to ship like a list of
[52:46] (3166.96s)
strings, like I think they chose a a
[52:50] (3170.00s)
reasonable level of complexity where it
[52:51] (3171.76s)
makes sense for that team so it works
[52:53] (3173.60s)
really well. But other cases, not so
[52:56] (3176.28s)
much. Eric, did you have an example of
[52:58] (3178.56s)
the nasty? Yeah. So the the first place
[53:01] (3181.52s)
we tried out server driven UI was our
[53:03] (3183.44s)
biggest most important service which is
[53:05] (3185.92s)
maybe not where you want to start with
[53:07] (3187.36s)
experimentation generally. Um on the
[53:09] (3189.60s)
surface though it made so it made a lot
[53:11] (3191.12s)
of sense. Like we had tons of logic in
[53:12] (3192.96s)
each client that went into determining
[53:15] (3195.28s)
how to display posts within a feed. Um
[53:18] (3198.24s)
you know overly smart clients aren't a
[53:19] (3199.92s)
good thing. Uh and the logic didn't even
[53:22] (3202.00s)
match between clients. Like there were
[53:24] (3204.00s)
times where you hold an Android and an
[53:25] (3205.28s)
iPhone next to each other and like the
[53:26] (3206.64s)
feeds would look different. not
[53:27] (3207.92s)
intentionally, just because we got the
[53:29] (3209.68s)
the logic wrong on one or the other and
[53:32] (3212.00s)
nobody knew which one was right.
[53:34] (3214.36s)
Um, but despite all the the good reasons
[53:38] (3218.32s)
that went into this, um, it was a
[53:40] (3220.48s)
decision that we've kind of ended up
[53:41] (3221.60s)
regretting to an extent uh, and that
[53:43] (3223.44s)
we're currently uh, working to walk back
[53:45] (3225.44s)
from, um, it turns out that even if the
[53:47] (3227.84s)
feed itself doesn't need, you know, the
[53:49] (3229.84s)
full post models to be able to display
[53:52] (3232.16s)
correctly, um, everything it links to
[53:54] (3234.88s)
still does. So, you know, if we make the
[53:57] (3237.36s)
feed server-driven UI and it no longer
[53:59] (3239.28s)
has any knowledge of the the backing
[54:01] (3241.76s)
models, um, we just end up having to do
[54:04] (3244.48s)
double fetching. Uh, we we have to fetch
[54:06] (3246.56s)
the server-driven UI definitions, then
[54:08] (3248.32s)
we have to fetch the actual models. And
[54:10] (3250.08s)
this just introduces double the
[54:12] (3252.48s)
opportunity for errors. Um, and it has
[54:15] (3255.12s)
led to lots of bugs that users see in in
[54:18] (3258.08s)
production. Um, I don't know if you've
[54:19] (3259.52s)
ever used the app and you've tried to
[54:21] (3261.04s)
tap on a post and nothing happens. Uh
[54:23] (3263.28s)
that's because one or the other of the
[54:25] (3265.04s)
fetches failed. Um so we're working on
[54:28] (3268.72s)
it. Yeah, it's interesting because ser
[54:32] (3272.00s)
server driven UI is is something that
[54:34] (3274.48s)
everyone eventually goes to because of
[54:36] (3276.16s)
the native mobile apps because the
[54:38] (3278.16s)
nature of mobile is if if you only have
[54:40] (3280.16s)
client side logic. You need to ship that
[54:42] (3282.48s)
code, maybe put it put it behind the
[54:44] (3284.72s)
feature flag, but it just takes, you
[54:46] (3286.40s)
know, if you want to add new business
[54:47] (3287.68s)
logic, it will take you at least a week
[54:49] (3289.28s)
or two weeks or however long it takes.
[54:51] (3291.68s)
So eventually everyone comes to a
[54:53] (3293.04s)
realization what if you know a what if
[54:55] (3295.68s)
we just had a web page wrapped into an
[54:57] (3297.76s)
app and that doesn't work but the next
[54:59] (3299.44s)
best thing is back in driven UI what
[55:01] (3301.84s)
what if we just have the business logic
[55:03] (3303.28s)
as as a JSON or or something that we
[55:05] (3305.60s)
download from the the website and it
[55:07] (3307.52s)
should work but I've seen so many times
[55:10] (3310.32s)
where like again like most companies
[55:12] (3312.32s)
don't talk about this publicly but it it
[55:14] (3314.80s)
becomes sour like it just doesn't really
[55:16] (3316.72s)
work out because I think eventually what
[55:19] (3319.12s)
I've seen realize is like you know we
[55:20] (3320.80s)
need to be backwards compatible. We need
[55:22] (3322.40s)
versioning. Uh we need to support older
[55:25] (3325.12s)
clients. We're now running into, oh, we
[55:27] (3327.12s)
want this feature that we didn't think
[55:28] (3328.24s)
about back then and now we could add it,
[55:29] (3329.92s)
but our older version doesn't have it.
[55:32] (3332.08s)
What what is your what is your take on
[55:33] (3333.52s)
why is this not taking off in mobile
[55:35] (3335.52s)
land in in general, right? Like it's it
[55:38] (3338.32s)
seems there's just you come around and
[55:40] (3340.16s)
learn a lot of these things. I I
[55:42] (3342.96s)
actually think that we shouldn't give up
[55:44] (3344.80s)
on the idea. All right. I I think it's
[55:48] (3348.32s)
like any idea that we have had
[55:51] (3351.00s)
and failed at or whiffed.
[55:55] (3355.64s)
Um you can say people you can say agile
[55:58] (3358.80s)
and it means different things to
[56:00] (3360.72s)
everybody. You can you can say
[56:03] (3363.48s)
modularization and you can name just as
[56:06] (3366.32s)
many times that has failed to deliver on
[56:08] (3368.40s)
its promises as it has worked. And so so
[56:13] (3373.20s)
I don't actually think that there's a
[56:15] (3375.28s)
real problem with the idea. I think
[56:18] (3378.24s)
there's a problem with an implementation
[56:20] (3380.08s)
that is that like works for the shape of
[56:22] (3382.16s)
the problem and we don't spend enough
[56:25] (3385.04s)
time making sure it is like like in this
[56:27] (3387.20s)
case I don't think we took enough time
[56:28] (3388.80s)
to make sure it was going to solve the
[56:30] (3390.64s)
Reddit shaped problem as opposed to
[56:32] (3392.96s)
serverdriven UI makes sense but don't
[56:35] (3395.52s)
actually like apply it to the actual
[56:38] (3398.40s)
reality of what our codebase and
[56:40] (3400.88s)
infrastructure looks like. Uh there were
[56:43] (3403.20s)
parts of our infrastructure that were
[56:44] (3404.56s)
not ready for it. we did not have an
[56:46] (3406.96s)
endto-end uh like commitment from
[56:48] (3408.96s)
everyone to work on the exact same plan
[56:51] (3411.60s)
at the exact same time in order to
[56:53] (3413.28s)
support it. Uh but I've also seen that
[56:56] (3416.40s)
happen with trunkbased development
[56:58] (3418.96s)
um and other things where it was like
[57:00] (3420.32s)
the fifth time you try you get it right
[57:02] (3422.88s)
and and then everyone is really happy
[57:04] (3424.72s)
with it. Um so I don't think it's
[57:08] (3428.00s)
necessarily the prescription that is the
[57:10] (3430.40s)
entire problem. I think it's a
[57:12] (3432.76s)
like underdeveloped implementation and
[57:16] (3436.36s)
like plan in place to make sure it can
[57:19] (3439.04s)
work in the cases that you want it to
[57:20] (3440.80s)
work. I want to I want to double click
[57:22] (3442.88s)
on on what Lori is saying with a
[57:24] (3444.72s)
specific example. So just in case any
[57:26] (3446.40s)
any product manager is listening who
[57:27] (3447.92s)
wants server-driven UI like the reason
[57:30] (3450.00s)
that managing that complexity is so
[57:32] (3452.08s)
important is that we know server-driven
[57:34] (3454.56s)
UI is possible and it can be done really
[57:37] (3457.20s)
well because web browsers exist. But
[57:40] (3460.48s)
that's the upper limit of this
[57:41] (3461.76s)
complexity and I don't have enough time
[57:43] (3463.60s)
to build Chrome really really well. So
[57:46] (3466.00s)
like if you want serverdriven UI and you
[57:48] (3468.16s)
want the full feature that you're
[57:49] (3469.28s)
specifying in a web browser, well all
[57:50] (3470.88s)
you have to do is spend several billion
[57:52] (3472.64s)
dollars. Uh if we if we control
[57:54] (3474.96s)
complexity well however we can we can
[57:57] (3477.12s)
definitely solve this problem. Just
[57:58] (3478.96s)
please no web browsers. But you also see
[58:01] (3481.60s)
that like web view implementations in
[58:04] (3484.08s)
mobile are often not great experiences
[58:06] (3486.00s)
for mobile developers. So like that
[58:08] (3488.24s)
there like there are ways in which we've
[58:10] (3490.08s)
tried to like bridge that at different
[58:12] (3492.40s)
times and sometimes it really works and
[58:14] (3494.40s)
sometimes it does not work. Um but I
[58:17] (3497.12s)
don't think we should stop trying on
[58:19] (3499.36s)
those like on these ideas because uh I
[58:23] (3503.44s)
think we all agree that our clients
[58:25] (3505.24s)
being simpler, having less logic in them
[58:28] (3508.32s)
and being more nimble is like those are
[58:30] (3510.32s)
all capabilities we want. We just
[58:31] (3511.76s)
haven't figured out how to deliver them
[58:33] (3513.12s)
well. Um, and in the meantime, we have
[58:36] (3516.00s)
weekly, sometimes more than once a week
[58:38] (3518.08s)
releases in order to keep the ability to
[58:40] (3520.64s)
change
[58:41] (3521.56s)
production. Um, no, nowhere near what
[58:45] (3525.20s)
our web our web platform can do in their
[58:47] (3527.68s)
continuous delivery pattern, but it's
[58:49] (3529.28s)
pretty much the fastest you can deploy
[58:50] (3530.80s)
on mobile. Oh, yeah. There's also like I
[58:53] (3533.60s)
I feel like for jetack or for excuse me
[58:55] (3535.84s)
for compose and for swift UI because the
[58:58] (3538.00s)
atoms are different we might be in a
[59:00] (3540.16s)
case where it's it's easier to try some
[59:02] (3542.16s)
of the things using those modern like uh
[59:04] (3544.72s)
lang excuse me the modern framework
[59:06] (3546.72s)
works that are closer to DSLs because if
[59:08] (3548.64s)
you think about a server driven UI thing
[59:10] (3550.88s)
it's probably really hard to do that in
[59:12] (3552.40s)
UI kit UI kit is not declarative since
[59:14] (3554.64s)
UI is declarative if you're shipping a
[59:16] (3556.08s)
declared spec it probably will change a
[59:20] (3560.80s)
and so you you've done a bunch of work
[59:22] (3562.64s)
over the last like three or four years
[59:24] (3564.16s)
starting from this this modernization
[59:25] (3565.76s)
you know you moved to to compose on on
[59:27] (3567.68s)
Android swift you well moving to swift
[59:29] (3569.92s)
UI on on iOS added in the the mono repo
[59:33] (3573.84s)
um we we didn't talk about it but but
[59:36] (3576.08s)
you you added code ownership and and you
[59:38] (3578.16s)
just did a bunch bunch of things that
[59:40] (3580.80s)
should that made things better in the
[59:42] (3582.96s)
end was and of course you onboarded so
[59:45] (3585.20s)
many new mobile engineers as well was
[59:47] (3587.44s)
this effort worth it like how can you
[59:49] (3589.44s)
tell how this this big modernization the
[59:52] (3592.72s)
core stack effort played off. I think we
[59:55] (3595.92s)
have really good answers to this on the
[59:58] (3598.40s)
DevX side. I think we have really great
[60:00] (3600.64s)
answers for this on the user side. Uh
[60:04] (3604.52s)
I know that our sentiment has improved
[60:10] (3610.16s)
from our developer sentiment and we are
[60:12] (3612.08s)
serving so many more developers than we
[60:14] (3614.40s)
were before. Um, and pretty much
[60:18] (3618.12s)
every stability and performance metric
[60:21] (3621.60s)
has benefited from the changes that
[60:23] (3623.60s)
we've made. Uh, but who wants to go
[60:27] (3627.56s)
first, Android or
[60:30] (3630.52s)
iOS? Sure, I'll go. Um, yeah, I mean,
[60:33] (3633.92s)
like Lori said, our our developer
[60:35] (3635.20s)
surveys have shown that people are just
[60:36] (3636.72s)
far happier than they used to be. Uh,
[60:38] (3638.56s)
those developer surveys were rough for a
[60:40] (3640.88s)
while. Um, and now they're overall like
[60:43] (3643.20s)
they're they're pretty positive. Um, but
[60:44] (3644.96s)
a lot of things have gotten easier.
[60:46] (3646.00s)
Onboarding is easier. We don't have to
[60:47] (3647.44s)
coach people into the, you know, myriad
[60:50] (3650.16s)
of of patterns that we have. Um, when I
[60:53] (3653.52s)
used to interview people, you know, they
[60:55] (3655.12s)
were all excited like, yeah, Reddit
[60:56] (3656.64s)
sounds so cool. I really want to work
[60:57] (3657.84s)
here. What's your tech stack look like?
[60:59] (3659.92s)
And I would tell them and I could just
[61:01] (3661.20s)
see their face like, uh, that sounds
[61:03] (3663.04s)
terrible. Um, and that's not the case
[61:05] (3665.12s)
anymore. Like people are excited. Uh,
[61:06] (3666.72s)
people like want to work in this kind of
[61:08] (3668.72s)
codebase. So, we we've seen a lot of
[61:10] (3670.08s)
really good stuff come out of it. um
[61:12] (3672.48s)
even the the types of engineers that we
[61:15] (3675.04s)
can hire. We can hire more junior
[61:16] (3676.88s)
engineers on the feature teams because
[61:19] (3679.36s)
you don't need to know all this, you
[61:21] (3681.76s)
know, legacy knowledge that there's no
[61:24] (3684.48s)
reason to know anymore uh for the most
[61:26] (3686.48s)
part. Um but and yeah, there's there's
[61:29] (3689.84s)
obviously all the the runtime userfacing
[61:31] (3691.60s)
benefits as well, but I don't know. I'm
[61:33] (3693.20s)
a developer. I care about developer
[61:34] (3694.56s)
experience.
[61:36] (3696.08s)
Brandon cares about texture crashes.
[61:39] (3699.44s)
I think uh iOS is a little lagging
[61:42] (3702.32s)
behind in that, but I think well
[61:45] (3705.04s)
emphatically it was worth it. Like
[61:46] (3706.64s)
there's if we wouldn't have done that, I
[61:49] (3709.52s)
can't imagine how the heck anybody would
[61:51] (3711.44s)
be productive uh uh with the the
[61:53] (3713.92s)
expectations that we would have had, but
[61:55] (3715.92s)
emphatically worth it. And I think even
[61:58] (3718.32s)
in cases where I feel like the tech
[62:00] (3720.88s)
needs to get better, it allows us to
[62:03] (3723.76s)
have a sort of specific path and a
[62:06] (3726.64s)
specific focus for people working on
[62:08] (3728.24s)
this. Like I love that we now have like
[62:10] (3730.64s)
iOS people who are the de facto GraphQL
[62:13] (3733.28s)
experts. That was not always the case.
[62:15] (3735.36s)
And now as they like iterate on that
[62:18] (3738.00s)
tooling and on those technologies, like
[62:20] (3740.48s)
everybody gets benefits. So we can
[62:22] (3742.88s)
progress in that area independently
[62:24] (3744.88s)
while I'm, you know, trying to figure
[62:26] (3746.48s)
out how we're going to get Swift UI into
[62:28] (3748.00s)
this thing. Um, and structured
[62:30] (3750.00s)
concurrency also introduces a lot of
[62:32] (3752.08s)
wrinkles on this. We have paths to like
[62:34] (3754.48s)
activate these projects and um, I would
[62:36] (3756.96s)
much rather be in this universe than the
[62:38] (3758.64s)
alternative.
[62:40] (3760.24s)
So, so I can give you some concrete
[62:42] (3762.16s)
examples of this. Uh, we used to see
[62:44] (3764.88s)
Slack messages in our like shared guild
[62:47] (3767.20s)
channels and you would have to figure
[62:48] (3768.96s)
out what somebody was doing at a really
[62:51] (3771.92s)
detailed level because it could be
[62:53] (3773.52s)
anything before you could help them. And
[62:56] (3776.00s)
so it was actually really hard to mentor
[62:57] (3777.68s)
people, especially in a remote first
[62:59] (3779.28s)
company. Um, you had to get a whole
[63:01] (3781.68s)
bunch of context before you could answer
[63:03] (3783.12s)
a question about why their build was
[63:04] (3784.48s)
broken or what they were trying to
[63:05] (3785.92s)
achieve. We have a much higher level of
[63:09] (3789.44s)
shared understanding when the question
[63:11] (3791.04s)
gets asked at this point because most
[63:13] (3793.52s)
people are following goldenish paths
[63:15] (3795.68s)
most of the time. So there's a lot less
[63:17] (3797.76s)
frustration burn a lot less burnout on
[63:20] (3800.00s)
the people who are both the subject
[63:22] (3802.16s)
matter experts and um the people who are
[63:25] (3805.28s)
trying to become them.
[63:27] (3807.56s)
Uh we did a whole bunch of uh analysis
[63:31] (3811.04s)
of our Devex improvements to try and
[63:33] (3813.20s)
prove out um not just by surveys but uh
[63:37] (3817.44s)
with some sort of quantitative analysis
[63:40] (3820.00s)
if they were worth doing. I really
[63:41] (3821.76s)
wanted to be able to kind of take the
[63:44] (3824.08s)
product approach of could we defend this
[63:46] (3826.48s)
sort of effort like we would defend a a
[63:49] (3829.36s)
product
[63:52] (3832.44s)
initiative. And we definitely saw that
[63:55] (3835.20s)
breaking up the monoliths and
[63:57] (3837.92s)
modularizing and giving people stronger
[63:59] (3839.84s)
ownership of their code areas improved a
[64:03] (3843.28s)
ton of productivity uh signals. Um
[64:07] (3847.92s)
people were building new features like
[64:09] (3849.92s)
Reddit recap with half the amount of
[64:11] (3851.76s)
people they did the previous year. Uh
[64:15] (3855.12s)
they were able to do they were able to
[64:17] (3857.20s)
finish their features sooner. So they
[64:18] (3858.96s)
would add these like extra bells and
[64:20] (3860.56s)
whistles to their actual like deliveries
[64:23] (3863.84s)
which had unintended consequences like
[64:26] (3866.40s)
they would introduce more uh uh
[64:30] (3870.00s)
animations and we'd be like where did
[64:31] (3871.60s)
those come from? Oh no, our performance.
[64:35] (3875.44s)
uh but but no all of those had like real
[64:38] (3878.16s)
business benefits from a developer
[64:40] (3880.16s)
efficiency and productivity uh
[64:42] (3882.40s)
perspective while increasing developer
[64:44] (3884.32s)
joy at the same time which was the kind
[64:45] (3885.76s)
of developer productivity we were after
[64:47] (3887.36s)
as platform team. The feature uh from a
[64:50] (3890.88s)
user side uh pretty much every one of
[64:54] (3894.00s)
our metrics that was bugging us at the
[64:56] (3896.40s)
beginning of this effort is in a much
[64:58] (3898.64s)
better and stable place and it very
[65:00] (3900.40s)
rarely sees regressions. our crashy
[65:03] (3903.76s)
rates benefited from going to uh Swift
[65:07] (3907.68s)
and Cotlin. Just from the like
[65:09] (3909.76s)
nullability perspective alone, we see
[65:11] (3911.60s)
very few NPE problems in production hot
[65:15] (3915.20s)
fixes associated with obvious avoidable
[65:18] (3918.24s)
problems like that. Um I think we we
[65:22] (3922.00s)
were up like 1.5 1.5 percentage points
[65:25] (3925.04s)
on crash rate, which is a ridiculously
[65:26] (3926.88s)
great improvement on Android. Um, iOS
[65:30] (3930.64s)
was always a little bit more stable
[65:31] (3931.76s)
because they don't have quite as many
[65:33] (3933.28s)
devices in the wild. Uh, but they also
[65:36] (3936.88s)
saw I think almost a 1% improvement over
[65:39] (3939.76s)
that sort of time period. I I never
[65:42] (3942.80s)
remember the percentages. I only I only
[65:44] (3944.64s)
remember when the problem completely
[65:45] (3945.84s)
goes away, right? And so so we are at a
[65:48] (3948.96s)
point of diminishing returns on
[65:50] (3950.40s)
investing in that space and we can focus
[65:53] (3953.04s)
on uh we then focused on startup times.
[65:56] (3956.96s)
those are down under like 3 to 4 seconds
[65:59] (3959.60s)
even in the P98 plus sort of range and
[66:03] (3963.60s)
they've stayed there for years and
[66:04] (3964.96s)
people have noticed um which allows us
[66:08] (3968.08s)
to basically move on to another problem
[66:10] (3970.56s)
we want to solve like scroll performance
[66:12] (3972.64s)
or video performance and working with
[66:14] (3974.16s)
the video team and stuff like that. So
[66:16] (3976.80s)
by kind of making these improvements and
[66:20] (3980.08s)
then putting uh policies into place to
[66:23] (3983.28s)
keep them relatively stable in those
[66:25] (3985.36s)
places without big regressions allows
[66:28] (3988.00s)
everyone to go redirect their time to
[66:29] (3989.68s)
what is the like most pressing thing
[66:31] (3991.28s)
that is uh in front of us either as a
[66:34] (3994.56s)
company or bothering our users the most
[66:37] (3997.36s)
and try and focus on improving that
[66:39] (3999.24s)
space. Um, and we can do that in part
[66:42] (4002.80s)
because everyone is kind of a little bit
[66:45] (4005.72s)
more similarly shaped, which allows us
[66:49] (4009.12s)
to make a huge amount of assumptions. We
[66:51] (4011.52s)
can assume that we can build a tool that
[66:53] (4013.20s)
will work for most of them most of the
[66:54] (4014.72s)
time, which we now do. We build a lot
[66:56] (4016.64s)
more tools and scripts and things to
[66:58] (4018.48s)
make things easy.
[67:00] (4020.32s)
Um, and we can build observability such
[67:02] (4022.80s)
that when we actually go looking at what
[67:04] (4024.56s)
the problem space looks like, we can
[67:06] (4026.40s)
actually build a map of what it looks
[67:07] (4027.84s)
like as opposed to it looks like a very
[67:11] (4031.20s)
strange world map with really strange
[67:13] (4033.28s)
boundary lines where you can't actually
[67:14] (4034.80s)
see the whole problem because everyone
[67:16] (4036.24s)
is doing something different. I want to
[67:17] (4037.76s)
double click on one of the things Lori
[67:19] (4039.28s)
said in case there are any prospective
[67:21] (4041.12s)
like uh uh modernization uh enthusiasts
[67:24] (4044.48s)
in the audience. Like we're not doing
[67:26] (4046.96s)
this because like we think we have a
[67:30] (4050.08s)
better solution than the feature teams.
[67:31] (4051.76s)
Like I feel like there's a bunch of
[67:33] (4053.52s)
boxes at Reddit where I don't I don't
[67:36] (4056.24s)
want you to have to think about how to
[67:37] (4057.84s)
interact with our GraphQL service. I
[67:39] (4059.44s)
just want you to like think about your
[67:40] (4060.72s)
feature and I want you to be able to be
[67:42] (4062.24s)
creative in the ways that she was
[67:43] (4063.92s)
describing. I love the idea that like
[67:45] (4065.44s)
you're adding animations and you're like
[67:47] (4067.12s)
you're actually bringing your creativity
[67:48] (4068.72s)
as an engineer to like the features
[67:50] (4070.96s)
you're
[67:51] (4071.72s)
building. The reason we're doing this is
[67:53] (4073.92s)
not like uh uh uh to take uh flexibility
[67:58] (4078.48s)
away from people. It's to eliminate a
[67:59] (4079.92s)
bunch of boring things so that you can
[68:01] (4081.68s)
do the actual important work. Uh if
[68:03] (4083.68s)
you're trying to do modernization, do it
[68:06] (4086.16s)
in service to your stakeholders. Do it
[68:08] (4088.16s)
in service to the teams that you
[68:09] (4089.44s)
support. Not because you think Swift is
[68:11] (4091.20s)
a cool language, not because you think
[68:12] (4092.72s)
Swift UI is a cool thing, because it has
[68:15] (4095.04s)
a benefit to the teams you support.
[68:17] (4097.20s)
That's a huge reason for us behind this.
[68:19] (4099.76s)
I I agree with that. I think that's one
[68:21] (4101.44s)
of the reasons why we focused on some of
[68:23] (4103.04s)
the places that people do not gravitate
[68:25] (4105.28s)
to like dependency injection. Like, can
[68:27] (4107.76s)
we make that less painful for people?
[68:29] (4109.76s)
Oh, yeah. Because nobody loves
[68:31] (4111.60s)
dependency injection with the possible
[68:33] (4113.12s)
exception of Drew until he was in charge
[68:34] (4114.80s)
of it. Um, and now can never not be
[68:38] (4118.56s)
anvil guy. Um, but we picked the places
[68:42] (4122.64s)
with pain points for our feature teams,
[68:45] (4125.60s)
not the ones that we were trying to like
[68:48] (4128.08s)
constrain them. To Brendan's point,
[68:51] (4131.84s)
um, and then you're in the enviable
[68:55] (4135.28s)
position of being a mobile platform team
[68:57] (4137.68s)
that is actually iOS and Android, so two
[69:00] (4140.88s)
pure native mobile platforms is quite
[69:02] (4142.72s)
rare in the industry. and al working
[69:04] (4144.32s)
with a large native mobile engineering
[69:06] (4146.40s)
team which obviously you you need a
[69:08] (4148.08s)
larger team to for a platform team to
[69:09] (4149.76s)
make sense. My question is what does it
[69:12] (4152.64s)
take for an iOS or Android engineer to
[69:16] (4156.32s)
work at a platform team like this in in
[69:18] (4158.88s)
terms of when you're hiring? What are
[69:20] (4160.72s)
the traits that you're looking for? Uh
[69:22] (4162.80s)
is is it is it a lot of internal
[69:24] (4164.40s)
transfers? I'm asking this because for a
[69:26] (4166.24s)
lot of mobile engineers this is a little
[69:28] (4168.00s)
bit of a dream to get there at some
[69:30] (4170.00s)
point if they're lucky enough to have
[69:31] (4171.52s)
either their organization or you know to
[69:33] (4173.84s)
look for the select few few companies
[69:35] (4175.60s)
that do have this this thing. What are
[69:38] (4178.24s)
ways that that mobile engineers who are
[69:40] (4180.16s)
doing either native or crossplatform can
[69:42] (4182.16s)
work towards skill sets or experience to
[69:44] (4184.96s)
increase their chances to later join a
[69:46] (4186.72s)
team like this? I'll take this first.
[69:50] (4190.52s)
Um so the people who have joined the
[69:53] (4193.68s)
teams in the last couple of years are a
[69:55] (4195.60s)
great mix of internal transfers and
[69:58] (4198.24s)
going out into the the hiring pool and
[70:01] (4201.28s)
hiring externally. Uh we often find
[70:05] (4205.48s)
people grow in their feature orgs to be
[70:09] (4209.04s)
a top performer and they know everything
[70:11] (4211.04s)
about their scope in that space but they
[70:13] (4213.12s)
have frustrations that they would really
[70:14] (4214.88s)
like to get resolved by platform
[70:17] (4217.52s)
solutions that would also impact other
[70:19] (4219.12s)
teams. They are great recruits and we
[70:21] (4221.36s)
have gotten a some really great people
[70:23] (4223.76s)
come into the platform teams who then
[70:26] (4226.32s)
just immediately turned around and
[70:27] (4227.84s)
helped solve real problems at Reddit
[70:30] (4230.48s)
with us and helped us understand them
[70:32] (4232.64s)
and scale them to everybody else. So I
[70:34] (4234.96s)
can think of a couple people who have
[70:36] (4236.16s)
joined our teams that absolutely meet
[70:38] (4238.40s)
that sort of like pattern. We've also
[70:41] (4241.52s)
gotten some really great talent out from
[70:43] (4243.52s)
other companies who have brought in
[70:44] (4244.88s)
fresh ideas from other companies at
[70:47] (4247.12s)
scale as well as from startups who are
[70:49] (4249.28s)
scrappy and Reddit is kind of messy and
[70:53] (4253.12s)
we often have zero to one problems that
[70:55] (4255.60s)
it does not take at scale experience to
[70:57] (4257.36s)
solve. It takes somebody looking at the
[70:58] (4258.80s)
problem and going I know exactly how to
[71:00] (4260.88s)
make this 100% better and just going and
[71:04] (4264.48s)
doing it. Um, so taking ownership over
[71:06] (4266.88s)
something and being practical and like
[71:09] (4269.84s)
having first principles is like
[71:11] (4271.28s)
extremely important. Uh, and then the
[71:14] (4274.00s)
last thing that I'm always looking for
[71:15] (4275.44s)
is uh, so it's a little different
[71:18] (4278.32s)
between the platform teams here, but I
[71:20] (4280.96s)
have a really robust rotation of DevX.
[71:23] (4283.68s)
Everyone on my team doesn't necessarily
[71:25] (4285.52s)
want to be Devx all the time, but they
[71:28] (4288.00s)
want to give
[71:29] (4289.00s)
back on the DevX side, at least part of
[71:32] (4292.32s)
their job, like at least 25% for
[71:35] (4295.08s)
everybody. Some people want to
[71:37] (4297.12s)
completely specialize on on the DevX
[71:40] (4300.08s)
side, but a whole bunch of people
[71:41] (4301.84s)
actually really enjoy helping other
[71:44] (4304.52s)
engineers work through their problems
[71:46] (4306.96s)
and and and such. So, I'm looking for
[71:50] (4310.40s)
like that interest in giving back to
[71:53] (4313.60s)
other internal engineers as well as
[71:55] (4315.92s)
thinking of end users at the same time.
[71:58] (4318.64s)
Um, but if they do join, they get to
[72:00] (4320.96s)
work with awesome people like Brandon
[72:02] (4322.40s)
and Eric who probably have a different
[72:04] (4324.40s)
perspective on what it what they're
[72:06] (4326.00s)
looking for on their platform teams. I
[72:09] (4329.28s)
my joke answer is that I don't know why
[72:13] (4333.52s)
someone would choose to do this. I just
[72:16] (4336.40s)
sort of kind of like stumbled into it.
[72:18] (4338.80s)
Um, it's very stressful and it's very
[72:21] (4341.44s)
hard. Um, having said that, uh, I would
[72:24] (4344.24s)
not choose any other position. I I want
[72:26] (4346.32s)
to be you will drag me from this team
[72:27] (4347.84s)
kicking and screaming. If I think Lori
[72:30] (4350.16s)
provided a good perspective. I want to I
[72:31] (4351.60s)
want to talk about like what I think is
[72:33] (4353.92s)
the most important thing for an IC who's
[72:37] (4357.68s)
who was trying to have a job on a
[72:39] (4359.44s)
platform team.
[72:41] (4361.52s)
You need to sit in the consequences of
[72:44] (4364.64s)
your decisions. Like you need to, in my
[72:48] (4368.32s)
opinion, you should try to work at a
[72:51] (4371.04s)
tech company for a year or two and
[72:53] (4373.76s)
actually see what happens after you ship
[72:56] (4376.16s)
a system and then the assumptions change
[72:58] (4378.96s)
and you have to figure out how to keep
[73:00] (4380.64s)
this thing going. There are systems that
[73:02] (4382.80s)
we have that have no joke been in our
[73:05] (4385.20s)
codebase for 5 years and the platform
[73:07] (4387.36s)
team has been like evaluating whether to
[73:09] (4389.92s)
replace them or how to keep them going.
[73:12] (4392.72s)
That's incredibly hard and I think
[73:14] (4394.56s)
that's uh we have very talented software
[73:17] (4397.84s)
engineers at um across like our iOS or
[73:20] (4400.56s)
right but I think the big difference
[73:22] (4402.32s)
between folks who are uh working in
[73:25] (4405.20s)
features and working this is it's more
[73:28] (4408.32s)
reasonable for a feature team to like
[73:30] (4410.08s)
take their code and after the product
[73:31] (4411.44s)
doesn't work they just kind of delete it
[73:33] (4413.20s)
and go on. Eric mentioned like the hawk
[73:34] (4414.88s)
is not in our codebase anymore. Most
[73:36] (4416.80s)
things that I've had to write at Reddit
[73:38] (4418.80s)
are still in the codebase. I wish they
[73:40] (4420.96s)
weren't. But you have to understand and
[73:42] (4422.88s)
I think the what you get out of that is
[73:45] (4425.12s)
you get a bunch of software design
[73:46] (4426.84s)
intuition. Um because you have to like
[73:49] (4429.84s)
re-evaluate your assumptions for an
[73:52] (4432.16s)
incredibly long time. Um if you can do
[73:54] (4434.40s)
that, you're probably ready for platform
[73:55] (4435.84s)
stuff. Um but take your time. Uh I don't
[73:59] (4439.04s)
want to burn you out before you're ready
[74:00] (4440.64s)
because this is hard. I I want to
[74:03] (4443.20s)
interject really quickly there. Uh, one
[74:05] (4445.36s)
of the things that Brandon mentioned
[74:06] (4446.56s)
that I think is really important and it
[74:08] (4448.32s)
definitely comes up in all of our
[74:09] (4449.44s)
interviews for platform roles. Uh, what
[74:13] (4453.60s)
we're not looking for is somebody that
[74:15] (4455.20s)
just wants to go introduce
[74:17] (4457.72s)
platform work that they are not going to
[74:20] (4460.40s)
use themselves or dog food and assume
[74:23] (4463.36s)
they can solve something without
[74:24] (4464.72s)
understanding the ground. And so that is
[74:28] (4468.32s)
one of the reasons why we like internal
[74:29] (4469.92s)
transfers or even feature team to
[74:32] (4472.56s)
platform team transfers or growth simply
[74:36] (4476.56s)
because if you take product thinking in
[74:38] (4478.64s)
here, we're just looking at a different
[74:40] (4480.16s)
set of users. Uh and if you do not take
[74:42] (4482.80s)
the feedback cycles from your
[74:44] (4484.56s)
developers, you will absolutely miss on
[74:46] (4486.72s)
what you try and deliver to them as a
[74:48] (4488.08s)
platform team. And that is a problem
[74:49] (4489.76s)
that we're always looking for like are
[74:51] (4491.44s)
we open to that feedback? Are we
[74:53] (4493.20s)
actually solving the problem that is the
[74:54] (4494.72s)
real problem at Reddit? Eric, what about
[74:58] (4498.08s)
Yeah, huge plus one to that. I don't
[74:59] (4499.44s)
think platform work is a great first
[75:01] (4501.44s)
job. Um although we have someone on our
[75:03] (4503.36s)
team who's doing great at as at it as
[75:05] (4505.76s)
their first job. Um but I don't think
[75:08] (4508.96s)
that there's really a blueprint for
[75:12] (4512.24s)
becoming a platform engineer. Like some
[75:14] (4514.08s)
people are jack of all trades because
[75:15] (4515.44s)
you need that to some extent. you have
[75:16] (4516.96s)
to know how the build system works, how
[75:18] (4518.96s)
to make a screen more performant, um
[75:21] (4521.60s)
just you know how how the compiler
[75:23] (4523.28s)
works. There's there's just so much
[75:25] (4525.12s)
knowledge that you need. And then others
[75:27] (4527.68s)
are just specialists. We have you know
[75:29] (4529.44s)
build experts. We have performance
[75:31] (4531.12s)
experts. We have people who um just go
[75:33] (4533.92s)
really deep in a certain area. So I
[75:36] (4536.16s)
don't know if there's a certain thing to
[75:38] (4538.96s)
do to become a platform engineer other
[75:41] (4541.80s)
than having experience across a lot of
[75:44] (4544.64s)
different things and just having an
[75:46] (4546.00s)
interest in it. I guess I do think that
[75:48] (4548.16s)
remember that you're talking to a couple
[75:50] (4550.08s)
of people
[75:51] (4551.08s)
at I would entertain the argument that
[75:53] (4553.36s)
when I joined Reddit it was probably not
[75:54] (4554.72s)
an air quotes startup but like it was a
[75:56] (4556.96s)
startup kind of environment but like
[75:58] (4558.96s)
both Eric and I like started in uh at
[76:02] (4562.48s)
Reddit when the teams were small enough
[76:04] (4564.32s)
that it was easier to get to that
[76:05] (4565.76s)
impact. So, one of the like things, you
[76:08] (4568.32s)
know, if you're trying to get onto a
[76:09] (4569.36s)
platform team, it's probably easier to
[76:11] (4571.20s)
go to a startup and get a bunch of that
[76:12] (4572.88s)
experience than it is to go to like a
[76:15] (4575.04s)
scaled uh uh platform because like our
[76:17] (4577.52s)
our bar of what we expect our engineers
[76:20] (4580.00s)
to do has gotten way higher. Like my my
[76:24] (4584.00s)
job now as a staff compared to my job
[76:26] (4586.08s)
like I think I was a staff four or so
[76:27] (4587.84s)
years ago, completely different
[76:29] (4589.84s)
completely different expectations. So, I
[76:31] (4591.52s)
think like being in a smaller org where
[76:33] (4593.44s)
you can get exposed to a lot of those uh
[76:35] (4595.84s)
different things that Eric is talking
[76:37] (4597.20s)
about is probably an easier path, but
[76:40] (4600.40s)
you should still apply. You might not uh
[76:42] (4602.40s)
you might not get accepted this round,
[76:43] (4603.84s)
but uh I'd still love to talk to you
[76:46] (4606.08s)
about how we do this. The last thing
[76:48] (4608.48s)
there is that like I want to push back
[76:50] (4610.56s)
on platforms being elite teams a little
[76:53] (4613.36s)
bit. We are not we're no smarter than
[76:54] (4614.80s)
any goals. I mostly from the perspective
[76:57] (4617.76s)
of I'm I'm always worried we're going to
[77:01] (4621.28s)
introduce
[77:02] (4622.44s)
a something that's going to reduce the
[77:05] (4625.04s)
the psychological safety of this group.
[77:07] (4627.76s)
They need to be able to break things in
[77:09] (4629.68s)
order to to make big
[77:11] (4631.88s)
improvements. And so having the ability
[77:14] (4634.40s)
to say you don't know an answer to
[77:15] (4635.92s)
something and not having any sort of
[77:17] (4637.92s)
problems with that and being able to
[77:20] (4640.40s)
just like really grow through blameless
[77:23] (4643.44s)
postmortem culture is extremely
[77:25] (4645.28s)
important to platform teams. Otherwise
[77:27] (4647.60s)
you always play it safe and you usually
[77:29] (4649.52s)
just continue to
[77:30] (4650.84s)
introduce friction to teams instead of
[77:34] (4654.08s)
actually solving their real problems to
[77:35] (4655.92s)
help them like reach their maximum
[77:38] (4658.00s)
potential as feature teams. It's too
[77:40] (4660.00s)
easy to be like, "We'll just add another
[77:41] (4661.20s)
lint rule so they avoid that foot gun
[77:43] (4663.28s)
and suddenly you have a gazillion of
[77:44] (4664.72s)
them and everything is slowing down
[77:46] (4666.72s)
because of all of their checks." Um, so,
[77:50] (4670.80s)
uh, I think there's also just the the
[77:54] (4674.80s)
brilliant a-hole sort of
[77:57] (4677.88s)
platform archetype that we specifically
[78:00] (4680.96s)
are not interested in. We like the
[78:03] (4683.36s)
brilliant uh, humble really wants to
[78:05] (4685.68s)
work with other people and help them
[78:07] (4687.20s)
solve their their problems, too.
[78:09] (4689.92s)
It is it is definitionally like a
[78:12] (4692.64s)
position of service. Like my job is to
[78:15] (4695.36s)
help engineers be more efficient. It's
[78:17] (4697.28s)
not to uh ivory tower designs and then
[78:20] (4700.24s)
pretend that I'm smarter than anyone
[78:21] (4701.60s)
else. I'm really not.
[78:24] (4704.08s)
No, this is nice to hear and I think
[78:25] (4705.76s)
it's just a good reminder as as
[78:27] (4707.12s)
companies grow like there's more
[78:28] (4708.56s)
opportunities. So like if you're lucky
[78:30] (4710.48s)
enough to work at a company which is
[78:31] (4711.84s)
hard to predict but if you know there
[78:33] (4713.60s)
are trajectories and like when companies
[78:35] (4715.60s)
live up to expectations they they will
[78:37] (4717.36s)
grow. It's just a lot of paths open up.
[78:39] (4719.36s)
May that be going to a platform team,
[78:42] (4722.32s)
may that be changing stacks, may that be
[78:44] (4724.32s)
going to a leadership position or you
[78:46] (4726.96s)
know transferring teams working on a lot
[78:48] (4728.96s)
of them. It's just a lot easier like and
[78:51] (4731.68s)
on the other hand you know companies
[78:52] (4732.88s)
that either shrink or or say stay kind
[78:56] (4736.20s)
flat everything will be a lot more
[78:58] (4738.40s)
challenging and difficult there. I I
[79:00] (4740.72s)
would say that
[79:01] (4741.88s)
like befriend your platform team is the
[79:04] (4744.96s)
best way to become a platform engineer
[79:07] (4747.84s)
someday. If you have a platform team,
[79:10] (4750.48s)
befriend them during hackathon weeks or
[79:12] (4752.72s)
do some mentorship and side projects.
[79:14] (4754.72s)
Almost everyone has done something like
[79:16] (4756.40s)
that before they end up joining our
[79:18] (4758.56s)
team. Uh but also we really like having
[79:21] (4761.28s)
really good partners on the on the
[79:23] (4763.20s)
feature teams themselves because they
[79:24] (4764.64s)
are very honest with us about what their
[79:26] (4766.48s)
real problems are and they are the best
[79:28] (4768.16s)
source of that.
[79:29] (4769.76s)
So there are also people who just never
[79:31] (4771.92s)
want to join a platform team because
[79:33] (4773.44s)
they're really user focused and that's
[79:35] (4775.68s)
the like the end user is the user they
[79:37] (4777.68s)
really really want to focus on with with
[79:39] (4779.76s)
their career and they are also some of
[79:42] (4782.32s)
our very best partners because they tell
[79:44] (4784.64s)
us what they're trying to achieve and we
[79:46] (4786.32s)
try and help them figure out how to do
[79:47] (4787.60s)
it. Um, they get they get early access
[79:51] (4791.92s)
to tech that's not ready yet. Like uh uh
[79:54] (4794.64s)
if we we have to find people who want to
[79:57] (4797.28s)
use Swift UI so we can deploy it at
[79:58] (4798.80s)
scale so we can verify all these issues.
[80:00] (4800.88s)
Like if you're getting buddy buddy with
[80:02] (4802.80s)
us, you're 100% going to be the first
[80:04] (4804.16s)
person in my head of like, oh well,
[80:05] (4805.76s)
search is a great partner for us on the
[80:07] (4807.68s)
iOS platform of like, yeah, we'll get
[80:09] (4809.52s)
feedback from them and see what Alex
[80:11] (4811.04s)
thinks of this. Yeah. Meanwhile, ads is
[80:14] (4814.08s)
a really great litmus test because they
[80:15] (4815.92s)
have to monetize every feature whether
[80:17] (4817.76s)
it's in legacy or modern and therefore
[80:19] (4819.52s)
they are very sensitive to slow
[80:21] (4821.12s)
migrations. Yep. So yeah, we go to
[80:23] (4823.68s)
different teams for different reasons
[80:24] (4824.88s)
and have like there's lots of ways to be
[80:27] (4827.12s)
part of the platform answer even if
[80:29] (4829.12s)
you're not on a platform team or if you
[80:31] (4831.04s)
choose to specialize in it. Nice. So as
[80:34] (4834.72s)
closing, let's just do some rapid
[80:36] (4836.24s)
questions where I'll I'll shoot the
[80:38] (4838.96s)
question and then you tell me what what
[80:40] (4840.64s)
pops up. So what's a framework that you
[80:42] (4842.88s)
really like for for its usability or
[80:45] (4845.60s)
elegance? If we're choosing usability
[80:48] (4848.40s)
and elegance, I have to pick Swift UI.
[80:50] (4850.72s)
But I was thinking about this question.
[80:52] (4852.08s)
I think my answer is actually lib
[80:54] (4854.08s)
GraphQL.js because that's the last
[80:55] (4855.76s)
framework that I uh interacted with that
[80:58] (4858.32s)
taught me a lot. Uh would recommend
[81:00] (4860.72s)
should read. I think for me uh it's
[81:03] (4863.68s)
compose. Um you know I love how
[81:05] (4865.68s)
maintainable and testable it is. It's
[81:07] (4867.20s)
just so much less boilerplate than
[81:08] (4868.64s)
anything I've used before. Um just
[81:10] (4870.96s)
really solid, you know, unidirectional
[81:12] (4872.72s)
design. Events work their way up, state
[81:14] (4874.48s)
works their way its way down. Um and you
[81:18] (4878.08s)
know, all these principles are are
[81:19] (4879.52s)
appealing for far beyond just the UI
[81:21] (4881.36s)
layer. Um you know, I know when you have
[81:22] (4882.80s)
a hammer, everything starts to look like
[81:24] (4884.08s)
a nail. Uh but you know, if I'm being
[81:26] (4886.08s)
honest, a lot of things have been
[81:27] (4887.36s)
looking like very appealing nails
[81:28] (4888.72s)
lately. Um, and you know at Reddit we we
[81:31] (4891.76s)
do use it for both our UI and our
[81:33] (4893.60s)
presentations layer, our presentation
[81:35] (4895.44s)
layer and it's been really great for us.
[81:39] (4899.12s)
I do also like compose the more I use
[81:41] (4901.12s)
it. Um, I was out of the actual IC world
[81:44] (4904.96s)
for a while but while but I have side
[81:46] (4906.96s)
projects that I've been really enjoying
[81:48] (4908.40s)
it again. Um, I picked a framework that
[81:51] (4911.68s)
is not a technology framework. Um I am
[81:55] (4915.68s)
often thinking about the western
[81:57] (4917.76s)
typology of organizational culture. It's
[82:00] (4920.56s)
in the accelerate book and I think about
[82:02] (4922.16s)
it a lot. Um it basically says that all
[82:05] (4925.44s)
cultures will eventually like settle
[82:08] (4928.40s)
into a pathological power oriented
[82:10] (4930.88s)
culture, a bureaucratic rule oriented
[82:12] (4932.96s)
culture or a generative
[82:14] (4934.24s)
performanceoriented culture. And when I
[82:17] (4937.28s)
first read about it, uh, I thought the
[82:20] (4940.56s)
whole answer was to keep moving people
[82:22] (4942.16s)
away from power cultures through
[82:25] (4945.04s)
bureaucratic into generative and that
[82:28] (4948.08s)
the best place for high performing teams
[82:29] (4949.84s)
was in generative. But now I have kind
[82:32] (4952.24s)
of come around to you have to choose the
[82:34] (4954.56s)
right tool for the job. And there's a
[82:36] (4956.32s)
reason why, for example, a QA team or um
[82:41] (4961.12s)
a like a
[82:42] (4962.84s)
deployment situation might actually be
[82:45] (4965.12s)
more rulesoriented and have a lot more
[82:47] (4967.28s)
process around it um than say how
[82:50] (4970.88s)
certain other teams could work. Um so
[82:53] (4973.04s)
how do you actually work together when
[82:54] (4974.88s)
you are like you have different cultures
[82:57] (4977.12s)
within teams? Um how do you get anything
[83:00] (4980.24s)
done when you have different incentives?
[83:02] (4982.32s)
So that's that's something that is I
[83:04] (4984.56s)
think of every
[83:05] (4985.80s)
uh people problem as a system design
[83:08] (4988.72s)
problem and so my answer is there are
[83:10] (4990.96s)
three types and how like what are what
[83:13] (4993.44s)
is the inter between them
[83:16] (4996.16s)
and then as closing what's a book that
[83:18] (4998.08s)
you would recommend and why I thought
[83:20] (5000.88s)
about this forever and I have to choose
[83:23] (5003.20s)
the KN&RC book um like I feel like it
[83:27] (5007.68s)
melted my brain a little bit when I
[83:29] (5009.44s)
really really understood that like
[83:30] (5010.88s)
object-oriented programing is like just
[83:33] (5013.36s)
C structures with function pointers
[83:34] (5014.88s)
inside of it. Like go through that book,
[83:37] (5017.12s)
type out every uh code example they have
[83:39] (5019.76s)
in it and I promise at the end of it you
[83:42] (5022.16s)
will be a confused programmer but you
[83:44] (5024.32s)
will be better. Can you repeat the book
[83:46] (5026.88s)
again? Oh the sorry the KNRC book the
[83:49] (5029.68s)
like classic Kernnegan and Richie uh
[83:51] (5031.68s)
Cbook. Oh did I get those names right?
[83:54] (5034.64s)
Carnean Richie. You did you did I have
[83:57] (5037.60s)
it in eight different forms. Is it like
[83:59] (5039.60s)
35 40 years old? And the book's probably
[84:01] (5041.92s)
older than me. Okay. Still still works.
[84:05] (5045.76s)
It was a It was a Bible for a reason. It
[84:08] (5048.24s)
is a good book. So good.
[84:11] (5051.40s)
Uh my So I read a lot. Uh I'm I'm a
[84:16] (5056.40s)
really big fan of taking a first
[84:18] (5058.00s)
principle and trying to get a whole
[84:19] (5059.60s)
bunch of people to try it at scale in
[84:21] (5061.92s)
order to like change one small thing. Um
[84:25] (5065.04s)
so I decided my my recommendation right
[84:27] (5067.76s)
now is Kent Beck's Tidy First. We read
[84:31] (5071.28s)
it as a we read it as a team last year
[84:33] (5073.76s)
and had a whole multi-day conversation
[84:36] (5076.96s)
about how we could incorporate Yeah. The
[84:39] (5079.20s)
little cat book. It's also extremely
[84:40] (5080.64s)
skinny, so you're not investing too
[84:42] (5082.16s)
much, but it has a lot of great ideas in
[84:44] (5084.40s)
it. It's it's skinny, but lots of good
[84:45] (5085.84s)
ideas. Um, so yeah, like I would
[84:49] (5089.40s)
suggest like pick up the book and then
[84:52] (5092.00s)
just you can open it up to any part and
[84:54] (5094.00s)
just pick one thing and try it for a few
[84:55] (5095.92s)
weeks and see if it changes your flow.
[84:58] (5098.56s)
Um but that that particular one I think
[85:01] (5101.44s)
has has uh launched a thousand little
[85:03] (5103.36s)
ideas with our team.
[85:06] (5106.24s)
I think for me um this is where I start
[85:09] (5109.20s)
to lose my credibility as an engineer.
[85:11] (5111.12s)
Um Project Hail Mary is my uh my fiction
[85:14] (5114.00s)
book recommendation. Fantastic. Couldn't
[85:16] (5116.16s)
put it down. Awesome. Well, thank thanks
[85:19] (5119.28s)
very much for for this interesting
[85:20] (5120.56s)
conversation on what it actually takes
[85:22] (5122.80s)
to build an app that is a lot more
[85:25] (5125.20s)
complex on the inside than you know a
[85:27] (5127.04s)
lot of people assume who who download it
[85:28] (5128.72s)
and use it. This was great.
[85:32] (5132.48s)
Tons of Yeah, this was lots of fun. I
[85:35] (5135.52s)
hope you enjoyed this behind thescenes
[85:36] (5136.88s)
look into how Reddit redid the core
[85:38] (5138.40s)
parts of their native iOS and Android
[85:39] (5139.92s)
apps over the course of several years.
[85:42] (5142.08s)
Thanks very much to Lauren, Brandon, and
[85:43] (5143.76s)
Eric. and you can find all of them in
[85:45] (5145.52s)
the show notes linked below. For more
[85:47] (5147.68s)
details on mobile engineering
[85:48] (5148.80s)
challenges, you can find longer deep
[85:50] (5150.16s)
dives into pragmatic engineer as linked
[85:51] (5151.84s)
in the show notes. I also wrote a book
[85:53] (5153.68s)
titled Building Mobile Apps at Scale
[85:55] (5155.44s)
that contains more pointers on this
[85:56] (5156.96s)
topic. If you enjoyed this podcast,
[85:58] (5158.96s)
please do subscribe on your favorite
[86:00] (5160.16s)
podcast platform and on YouTube. This
[86:02] (5162.32s)
helps more people discover the podcast
[86:04] (5164.00s)
and a special thank you if you leave a
[86:05] (5165.52s)
rating. Thanks and see you in the next