0:03
great uh well great to be here so today
0:06
great uh well great to be here so today
0:06
great uh well great to be here so today I'm going to talk about app
0:09
I'm going to talk about app
0:09
I'm going to talk about app configuration now if you've heard of
0:10
configuration now if you've heard of
0:10
configuration now if you've heard of feature Flags you can think of them as
0:13
feature Flags you can think of them as
0:13
feature Flags you can think of them as the tip of the app configuration shaped
0:16
the tip of the app configuration shaped
0:16
the tip of the app configuration shaped Iceberg now the best way to understand
0:18
Iceberg now the best way to understand
0:18
Iceberg now the best way to understand what app configuration is is to see it
0:21
what app configuration is is to see it
0:21
what app configuration is is to see it in action so let's imagine we're a SAS
0:23
in action so let's imagine we're a SAS
0:23
in action so let's imagine we're a SAS company called
0:25
company called potion and this is the uh this is our
0:29
potion and this is the uh this is our
0:29
potion and this is the uh this is our mobile app and it's the plans page of
0:31
mobile app and it's the plans page of
0:31
mobile app and it's the plans page of our mobile app where users can subscribe
0:34
our mobile app where users can subscribe
0:34
our mobile app where users can subscribe to one of our paid plans now let's say
0:37
to one of our paid plans now let's say
0:37
to one of our paid plans now let's say the marketing team wants to run a 20%
0:39
the marketing team wants to run a 20%
0:39
the marketing team wants to run a 20% discount across all of the paid plans so
0:42
discount across all of the paid plans so
0:42
discount across all of the paid plans so they ask us the engineering team for
0:45
they ask us the engineering team for
0:45
they ask us the engineering team for help so what we'll do is go into our
0:48
help so what we'll do is go into our
0:48
help so what we'll do is go into our code base and we'll write some code to
0:52
code base and we'll write some code to
0:52
code base and we'll write some code to implement this uh 20% discount for them
0:58
implement this uh 20% discount for them
0:58
implement this uh 20% discount for them so we'll do that and once we're happy
1:03
so we'll do that and once we're happy
1:03
so we'll do that and once we're happy with how that looks we'll deploy it to a
1:05
with how that looks we'll deploy it to a
1:05
with how that looks we'll deploy it to a test or staging environment and and
1:08
test or staging environment and and
1:08
test or staging environment and and we'll send the marketing team a link so
1:10
we'll send the marketing team a link so
1:10
we'll send the marketing team a link so they can test it out and make sure that
1:12
they can test it out and make sure that
1:12
they can test it out and make sure that this discount looks good so they do that
1:16
this discount looks good so they do that
1:16
this discount looks good so they do that and they tell us that the discount looks
1:17
and they tell us that the discount looks
1:17
and they tell us that the discount looks good we're ready for it to go to
1:19
good we're ready for it to go to
1:19
good we're ready for it to go to production so we submit this code to
1:22
production so we submit this code to
1:22
production so we submit this code to production now and then once it's live
1:24
production now and then once it's live
1:24
production now and then once it's live We Tell the marketing team and then they
1:26
We Tell the marketing team and then they
1:26
We Tell the marketing team and then they confirm that it looks good again uh and
1:29
confirm that it looks good again uh and
1:29
confirm that it looks good again uh and the discount
1:30
the discount is is running in
1:31
is is running in production but then after a few days the
1:34
production but then after a few days the
1:34
production but then after a few days the marketing team says that they want to
1:36
marketing team says that they want to
1:36
marketing team says that they want to pause the discount so we have to go back
1:39
pause the discount so we have to go back
1:39
pause the discount so we have to go back into the code base and make the change
1:42
into the code base and make the change
1:42
into the code base and make the change to disable the
1:44
to disable the discount and then we have to deploy this
1:46
discount and then we have to deploy this
1:46
discount and then we have to deploy this to production which takes some time and
1:49
to production which takes some time and
1:50
to production which takes some time and then we'll tell the marketing team it's
1:51
then we'll tell the marketing team it's
1:51
then we'll tell the marketing team it's paused they confirm that it's paused uh
1:54
paused they confirm that it's paused uh
1:54
paused they confirm that it's paused uh and then we don't hear from them for a
1:55
and then we don't hear from them for a
1:55
and then we don't hear from them for a while but then after a few days they get
1:58
while but then after a few days they get
1:58
while but then after a few days they get back to us and they say they're ready to
2:00
back to us and they say they're ready to
2:00
back to us and they say they're ready to resume the
2:01
resume the discounts now this is getting a bit
2:05
discounts now this is getting a bit
2:05
discounts now this is getting a bit tedious for us so we decide to put the
2:09
tedious for us so we decide to put the
2:09
tedious for us so we decide to put the discount behind a feature flag that the
2:12
discount behind a feature flag that the
2:12
discount behind a feature flag that the marketing team can toggle on and off
2:14
marketing team can toggle on and off
2:14
marketing team can toggle on and off themselves now we've already set up a
2:16
themselves now we've already set up a
2:16
themselves now we've already set up a feature flag system in our app called
2:18
feature flag system in our app called
2:18
feature flag system in our app called hypertune so what we'll do is go into
2:21
hypertune so what we'll do is go into
2:21
hypertune so what we'll do is go into the UI for
2:24
the UI for hypertune and we'll create a new feature
2:27
hypertune and we'll create a new feature
2:27
hypertune and we'll create a new feature flag and we'll call it
2:30
flag and we'll call it
2:30
flag and we'll call it is Discount
2:31
is Discount enabled and this will be a Boolean uh
2:34
enabled and this will be a Boolean uh
2:34
enabled and this will be a Boolean uh which just means it could be either on
2:36
which just means it could be either on
2:36
which just means it could be either on or off and we'll leave it off for now
2:38
or off and we'll leave it off for now
2:38
or off and we'll leave it off for now and we'll save that then we'll go into
2:41
and we'll save that then we'll go into
2:41
and we'll save that then we'll go into our code base and we'll run npx
2:44
our code base and we'll run npx
2:45
our code base and we'll run npx hypertune to regenerate our type safe
2:48
hypertune to regenerate our type safe
2:48
hypertune to regenerate our type safe client and we'll use the feature flag in
2:51
client and we'll use the feature flag in
2:51
client and we'll use the feature flag in our code so we'll write hypertune do is
2:54
our code so we'll write hypertune do is
2:54
our code so we'll write hypertune do is Discount enabled and we'll pass a full
2:57
Discount enabled and we'll pass a full
2:57
Discount enabled and we'll pass a full back value of false and then will deploy
3:00
back value of false and then will deploy
3:00
back value of false and then will deploy this to production and then we'll tell
3:02
this to production and then we'll tell
3:02
this to production and then we'll tell the marketing team they can now control
3:05
the marketing team they can now control
3:05
the marketing team they can now control whether the discount is enabled from
3:07
whether the discount is enabled from
3:07
whether the discount is enabled from this flag in the UI so right now it's
3:10
this flag in the UI so right now it's
3:10
this flag in the UI so right now it's off but they can flip it on and then hit
3:13
off but they can flip it on and then hit
3:13
off but they can flip it on and then hit save and then the discount
3:16
save and then the discount
3:16
save and then the discount appears so this is great as now they can
3:20
appears so this is great as now they can
3:20
appears so this is great as now they can make changes to the discount themselves
3:23
make changes to the discount themselves
3:23
make changes to the discount themselves without having to ask us every time and
3:25
without having to ask us every time and
3:25
without having to ask us every time and then we don't have to wait for them to
3:27
then we don't have to wait for them to
3:27
then we don't have to wait for them to tell us when the discount should be live
3:29
tell us when the discount should be live
3:29
tell us when the discount should be live so our work streams are decoupled and we
3:31
so our work streams are decoupled and we
3:31
so our work streams are decoupled and we can both move a lot
3:33
can both move a lot faster and because it's a flag they can
3:36
faster and because it's a flag they can
3:36
faster and because it's a flag they can also add more complex logic now to say
3:38
also add more complex logic now to say
3:38
also add more complex logic now to say who the discount should be on for so
3:41
who the discount should be on for so
3:41
who the discount should be on for so they actually decide that they only want
3:43
they actually decide that they only want
3:43
they actually decide that they only want to run the discount in the UK so they
3:45
to run the discount in the UK so they
3:45
to run the discount in the UK so they can add a rule to say if the users's
3:49
can add a rule to say if the users's
3:49
can add a rule to say if the users's country is one of this list of countries
3:52
country is one of this list of countries
3:52
country is one of this list of countries and they add the UK here then the
3:54
and they add the UK here then the
3:54
and they add the UK here then the discount is on otherwise for users in
3:57
discount is on otherwise for users in
3:57
discount is on otherwise for users in all the other countries it's off
4:00
all the other countries it's off
4:00
all the other countries it's off and whenever they make a change here
4:01
and whenever they make a change here
4:01
and whenever they make a change here it's updated instantly so they don't
4:03
it's updated instantly so they don't
4:03
it's updated instantly so they don't have to wait for a code deployment or an
4:05
have to wait for a code deployment or an
4:05
have to wait for a code deployment or an app release they can see their changes
4:07
app release they can see their changes
4:07
app release they can see their changes live immediately uh and the other uh
4:11
live immediately uh and the other uh
4:11
live immediately uh and the other uh great thing about having this flag is
4:14
great thing about having this flag is
4:14
great thing about having this flag is they can also run an AB test on the
4:16
they can also run an AB test on the
4:17
they can also run an AB test on the discount so rather than it just be on
4:19
discount so rather than it just be on
4:20
discount so rather than it just be on for everyone they can drop in an AB test
4:23
for everyone they can drop in an AB test
4:23
for everyone they can drop in an AB test here and they can set it on for half of
4:25
here and they can set it on for half of
4:25
here and they can set it on for half of users off for the other half and then
4:27
users off for the other half and then
4:27
users off for the other half and then this would let them measure the impact
4:30
this would let them measure the impact
4:30
this would let them measure the impact of running the discount on the metrics
4:32
of running the discount on the metrics
4:32
of running the discount on the metrics they care about like signups Revenue
4:35
they care about like signups Revenue
4:35
they care about like signups Revenue profit and so
4:37
profit and so on so we don't hear from the marketing
4:39
on so we don't hear from the marketing
4:39
on so we don't hear from the marketing team for a while because this system is
4:41
team for a while because this system is
4:41
team for a while because this system is working pretty well uh they're not
4:44
working pretty well uh they're not
4:44
working pretty well uh they're not bothering us to to change the discount
4:46
bothering us to to change the discount
4:46
bothering us to to change the discount logic um but then one day we hear from
4:49
logic um but then one day we hear from
4:49
logic um but then one day we hear from them and they tell us that instead of
4:52
them and they tell us that instead of
4:52
them and they tell us that instead of running a 20% discount here they want to
4:55
running a 20% discount here they want to
4:55
running a 20% discount here they want to run a 40% discount now the problem is
4:59
run a 40% discount now the problem is
4:59
run a 40% discount now the problem is that there's % was hardcoded in the code
5:03
that there's % was hardcoded in the code
5:03
that there's % was hardcoded in the code base so we need to change it for them to
5:05
base so we need to change it for them to
5:05
base so we need to change it for them to 40% but we could just change it for them
5:08
40% but we could just change it for them
5:08
40% but we could just change it for them but then that would lead to that same
5:09
but then that would lead to that same
5:09
but then that would lead to that same slow back and forth process that we had
5:12
slow back and forth process that we had
5:12
slow back and forth process that we had before we had the feature flag so let's
5:16
before we had the feature flag so let's
5:16
before we had the feature flag so let's see if there's something that we can do
5:17
see if there's something that we can do
5:17
see if there's something that we can do to give them control over this
5:19
to give them control over this
5:19
to give them control over this percentage as
5:22
percentage as well so one thing that we can do is in
5:25
well so one thing that we can do is in
5:25
well so one thing that we can do is in the hypertune UI instead of returning uh
5:29
the hypertune UI instead of returning uh
5:29
the hypertune UI instead of returning uh a true or false Boolean from this flag
5:32
a true or false Boolean from this flag
5:32
a true or false Boolean from this flag we could return a whole discount object
5:35
we could return a whole discount object
5:35
we could return a whole discount object with subfields to say whether the
5:38
with subfields to say whether the
5:38
with subfields to say whether the discount should be on and another field
5:40
discount should be on and another field
5:40
discount should be on and another field to say what the percentage should be so
5:44
to say what the percentage should be so
5:44
to say what the percentage should be so to do that we'll go into the schema in
5:47
to do that we'll go into the schema in
5:47
to do that we'll go into the schema in hypertune and we'll Define a new object
5:51
hypertune and we'll Define a new object
5:51
hypertune and we'll Define a new object type called
5:53
type called discount uh so we've actually set one up
5:56
discount uh so we've actually set one up
5:56
discount uh so we've actually set one up here already uh and we've got got a
6:00
here already uh and we've got got a
6:00
here already uh and we've got got a field uh this Boolean field uh called is
6:04
field uh this Boolean field uh called is
6:04
field uh this Boolean field uh called is enabled and another field uh called
6:07
enabled and another field uh called
6:07
enabled and another field uh called percentage which is a
6:09
percentage which is a
6:09
percentage which is a float um and we'll remove this field for
6:15
float um and we'll remove this field for
6:15
float um and we'll remove this field for now so we'll deprecate
6:18
now so we'll deprecate
6:18
now so we'll deprecate this uh Boolean flag and we'll add a new
6:22
this uh Boolean flag and we'll add a new
6:22
this uh Boolean flag and we'll add a new flag called
6:24
flag called discount and instead of returning a
6:26
discount and instead of returning a
6:26
discount and instead of returning a Boolean we'll return a discount object
6:31
Boolean we'll return a discount object
6:31
Boolean we'll return a discount object type we'll save that and then we'll go
6:34
type we'll save that and then we'll go
6:35
type we'll save that and then we'll go back into the code base and run npx
6:37
back into the code base and run npx
6:37
back into the code base and run npx hypertune to regenerate our
6:40
hypertune to regenerate our
6:40
hypertune to regenerate our client and then we'll see a type error
6:43
client and then we'll see a type error
6:43
client and then we'll see a type error where we're still using that deprecated
6:44
where we're still using that deprecated
6:45
where we're still using that deprecated flag so we'll replace that with a new
6:48
flag so we'll replace that with a new
6:48
flag so we'll replace that with a new flag which is hypertune do
6:50
flag which is hypertune do
6:50
flag which is hypertune do discount do is
6:53
discount do is enabled and we'll also replace this
6:55
enabled and we'll also replace this
6:55
enabled and we'll also replace this hardcoded percentage with hypertune do
6:58
hardcoded percentage with hypertune do
6:58
hardcoded percentage with hypertune do discount
7:00
discount do percentage and we'll pass a fullback
7:02
do percentage and we'll pass a fullback
7:03
do percentage and we'll pass a fullback value of zero here so we'll deploy this
7:06
value of zero here so we'll deploy this
7:06
value of zero here so we'll deploy this to production and then we'll tell the
7:08
to production and then we'll tell the
7:08
to production and then we'll tell the marketing team that they can now control
7:11
marketing team that they can now control
7:11
marketing team that they can now control whether the discount is on or off just
7:13
whether the discount is on or off just
7:13
whether the discount is on or off just like before but now they can also
7:16
like before but now they can also
7:16
like before but now they can also control the percentage so instead of 20%
7:20
control the percentage so instead of 20%
7:20
control the percentage so instead of 20% they can have 40%
7:23
they can have 40% here uh but just like before they can
7:26
here uh but just like before they can
7:26
here uh but just like before they can also have complex logic to say who the
7:29
also have complex logic to say who the
7:29
also have complex logic to say who the discount should be enabled for so they
7:31
discount should be enabled for so they
7:31
discount should be enabled for so they can have it on for specific countries uh
7:35
can have it on for specific countries uh
7:35
can have it on for specific countries uh and they can have that same kind of
7:36
and they can have that same kind of
7:36
and they can have that same kind of logic for the percentage so they can
7:37
logic for the percentage so they can
7:37
logic for the percentage so they can have different percentages for different
7:39
have different percentages for different
7:39
have different percentages for different users or even AB test the percentage to
7:42
users or even AB test the percentage to
7:42
users or even AB test the percentage to see which one which percentage works
7:45
see which one which percentage works
7:45
see which one which percentage works best so they're pretty happy with this
7:47
best so they're pretty happy with this
7:48
best so they're pretty happy with this system uh they're pretty excited and in
7:50
system uh they're pretty excited and in
7:50
system uh they're pretty excited and in their excitement they ask whether they
7:53
their excitement they ask whether they
7:53
their excitement they ask whether they can also control the copy which we show
7:55
can also control the copy which we show
7:55
can also control the copy which we show next to the discount over here as well
7:57
next to the discount over here as well
7:57
next to the discount over here as well so instead of summer sale
8:00
so instead of summer sale
8:00
so instead of summer sale they can have different messaging and
8:02
they can have different messaging and
8:02
they can have different messaging and see which one works
8:04
see which one works best so to do that we'll go back into
8:07
best so to do that we'll go back into
8:07
best so to do that we'll go back into the schema for our discount object type
8:11
the schema for our discount object type
8:11
the schema for our discount object type and we'll add a new field called name
8:15
and we'll add a new field called name
8:15
and we'll add a new field called name which we set to a string and here's
8:17
which we set to a string and here's
8:17
which we set to a string and here's where we'll control the copy that we
8:19
where we'll control the copy that we
8:19
where we'll control the copy that we show to the
8:20
show to the user so we'll save that and then we'll
8:23
user so we'll save that and then we'll
8:23
user so we'll save that and then we'll go into our codebase and run npx
8:27
hypertune and then we'll replace this
8:31
hypertune and then we'll replace this
8:31
hypertune and then we'll replace this hardcoded copy with hypertune do
8:35
hardcoded copy with hypertune do
8:35
hardcoded copy with hypertune do discount. name and we'll pass a fullback
8:38
discount. name and we'll pass a fullback
8:39
discount. name and we'll pass a fullback value of just
8:41
value of just discount so we'll deploy this to
8:43
discount so we'll deploy this to
8:43
discount so we'll deploy this to production and now the marketing team
8:45
production and now the marketing team
8:45
production and now the marketing team can control the copy of the discount too
8:48
can control the copy of the discount too
8:48
can control the copy of the discount too so by default it's summer sale uh but
8:53
so by default it's summer sale uh but
8:53
so by default it's summer sale uh but like we said they want to test different
8:55
like we said they want to test different
8:55
like we said they want to test different variations of this messaging to see
8:57
variations of this messaging to see
8:57
variations of this messaging to see which one works best so instead of
8:59
which one works best so instead of
8:59
which one works best so instead of sumale they decide to drop in an ABC
9:03
sumale they decide to drop in an ABC
9:03
sumale they decide to drop in an ABC test to test a few different variations
9:06
test to test a few different variations
9:06
test to test a few different variations of this
9:07
of this copy so they have summer sale summer
9:10
copy so they have summer sale summer
9:10
copy so they have summer sale summer sale ends soon and summer sale ends
9:14
sale ends soon and summer sale ends
9:14
sale ends soon and summer sale ends today
9:17
[Music] and now instead of running a traditional
9:21
and now instead of running a traditional
9:21
and now instead of running a traditional experiment where they wait for the
9:24
experiment where they wait for the
9:24
experiment where they wait for the experiment to run and then see which
9:26
experiment to run and then see which
9:26
experiment to run and then see which variation works best and then ship that
9:29
variation works best and then ship that
9:29
variation works best and then ship that VAR
9:29
VAR to 100% they instead go to the
9:34
to 100% they instead go to the
9:34
to 100% they instead go to the experiment page in hypertune and they
9:38
experiment page in hypertune and they
9:38
experiment page in hypertune and they set it to a machine learning Loop so
9:42
set it to a machine learning Loop so
9:42
set it to a machine learning Loop so that hypertune will automatically
9:45
that hypertune will automatically
9:45
that hypertune will automatically Converge on the best variant over time
9:48
Converge on the best variant over time
9:48
Converge on the best variant over time to maximize the number of
9:50
to maximize the number of
9:50
to maximize the number of upgrades and it can also take into
9:53
upgrades and it can also take into
9:53
upgrades and it can also take into account user attributes to learn if the
9:55
account user attributes to learn if the
9:56
account user attributes to learn if the best variant is different for different
9:58
best variant is different for different
9:58
best variant is different for different types of users
10:01
types of users so they're pretty happy with this system
10:03
so they're pretty happy with this system
10:03
so they're pretty happy with this system now they can control the copy
10:06
now they can control the copy
10:06
now they can control the copy automatically personalize it to each
10:09
automatically personalize it to each
10:09
automatically personalize it to each user with machine learning uh control
10:12
user with machine learning uh control
10:12
user with machine learning uh control the percentage and whether the discount
10:14
the percentage and whether the discount
10:14
the percentage and whether the discount is enabled so we don't hear from them
10:17
is enabled so we don't hear from them
10:17
is enabled so we don't hear from them for a long while they're happy using
10:19
for a long while they're happy using
10:19
for a long while they're happy using this
10:20
this system but then one day we hear from
10:24
system but then one day we hear from
10:24
system but then one day we hear from them and they come to us with a complex
10:26
them and they come to us with a complex
10:26
them and they come to us with a complex use case they want to run a 20 20%
10:30
use case they want to run a 20 20%
10:30
use case they want to run a 20 20% discount for all of their users but they
10:33
discount for all of their users but they
10:33
discount for all of their users but they want an additional 10% discount for
10:35
want an additional 10% discount for
10:35
want an additional 10% discount for users who enter a special discount code
10:38
users who enter a special discount code
10:38
users who enter a special discount code so they need a way to run multiple
10:41
so they need a way to run multiple
10:41
so they need a way to run multiple overlapping discounts at the same time
10:44
overlapping discounts at the same time
10:44
overlapping discounts at the same time so now instead of a flag which returns
10:48
so now instead of a flag which returns
10:48
so now instead of a flag which returns just one discount object we actually
10:51
just one discount object we actually
10:51
just one discount object we actually want a flag which returns a list of
10:53
want a flag which returns a list of
10:53
want a flag which returns a list of discount
10:54
discount objects so we'll deprecate this discount
10:59
objects so we'll deprecate this discount
10:59
objects so we'll deprecate this discount flag and we'll create a new flag called
11:02
flag and we'll create a new flag called
11:02
flag and we'll create a new flag called discounts which returns a list of
11:09
discounts and we'll save that and then
11:12
discounts and we'll save that and then
11:13
discounts and we'll save that and then go back into our codebase uh before we
11:16
go back into our codebase uh before we
11:16
go back into our codebase uh before we before we regenerate regenerate the
11:18
before we regenerate regenerate the
11:18
before we regenerate regenerate the client we'll actually go into the schema
11:21
client we'll actually go into the schema
11:21
client we'll actually go into the schema uh and we'll actually switch into
11:23
uh and we'll actually switch into
11:23
uh and we'll actually switch into graphql mode and we'll see that new
11:26
graphql mode and we'll see that new
11:26
graphql mode and we'll see that new discounts flag that we created
11:29
discounts flag that we created
11:29
discounts flag that we created and we'll actually add an argument to
11:31
and we'll actually add an argument to
11:31
and we'll actually add an argument to this flag called
11:33
this flag called code which will be a string and this
11:36
code which will be a string and this
11:36
code which will be a string and this will be the discount code which the user
11:37
will be the discount code which the user
11:37
will be the discount code which the user enters and we'll be able to use that in
11:40
enters and we'll be able to use that in
11:40
enters and we'll be able to use that in our Logic for the discounts flag so
11:43
our Logic for the discounts flag so
11:43
our Logic for the discounts flag so we'll save
11:44
we'll save that then we'll regenerate our
11:51
client and then we'll see a type eror
11:54
client and then we'll see a type eror
11:54
client and then we'll see a type eror where we're still using this old
11:56
where we're still using this old
11:56
where we're still using this old discount
11:58
discount flag uh and instead we will use this new
12:02
flag uh and instead we will use this new
12:02
flag uh and instead we will use this new hypertune do discounts
12:04
hypertune do discounts
12:04
hypertune do discounts flag uh and we'll pass in the code that
12:08
flag uh and we'll pass in the code that
12:08
flag uh and we'll pass in the code that the user enters as an argument and then
12:10
the user enters as an argument and then
12:10
the user enters as an argument and then we'll map over each discount converting
12:12
we'll map over each discount converting
12:12
we'll map over each discount converting it into a plain JavaScript object and
12:15
it into a plain JavaScript object and
12:15
it into a plain JavaScript object and then we'll filter them by the discounts
12:17
then we'll filter them by the discounts
12:17
then we'll filter them by the discounts which are
12:19
which are enabled so we'll deploy all this to
12:21
enabled so we'll deploy all this to
12:21
enabled so we'll deploy all this to production and then we'll tell the
12:23
production and then we'll tell the
12:23
production and then we'll tell the marketing team they can now add as many
12:25
marketing team they can now add as many
12:26
marketing team they can now add as many discounts as they like to this list flag
12:29
discounts as they like to this list flag
12:30
discounts as they like to this list flag so the first thing they do is they add a
12:32
so the first thing they do is they add a
12:32
so the first thing they do is they add a discount called Summer sale which is on
12:35
discount called Summer sale which is on
12:35
discount called Summer sale which is on for everyone and it uh is for
12:40
for everyone and it uh is for
12:40
for everyone and it uh is for 20% and they save that and they can see
12:43
20% and they save that and they can see
12:43
20% and they save that and they can see that live in the app immediately and
12:46
that live in the app immediately and
12:46
that live in the app immediately and then they add a second
12:47
then they add a second
12:47
then they add a second discount but this time it's only enabled
12:51
discount but this time it's only enabled
12:51
discount but this time it's only enabled if the user has entered a special
12:55
if the user has entered a special
12:55
if the user has entered a special code uh which is is react and
13:02
code uh which is is react and
13:02
code uh which is is react and chill uh and otherwise it's off and this
13:06
chill uh and otherwise it's off and this
13:07
chill uh and otherwise it's off and this is for an additional
13:08
is for an additional
13:08
is for an additional 10% and this will be the react and chill
13:13
10% and this will be the react and chill
13:13
10% and this will be the react and chill discount so they save
13:17
discount so they save
13:17
discount so they save that and now we don't see the discount
13:20
that and now we don't see the discount
13:20
that and now we don't see the discount yet but if the user
13:23
yet but if the user enters that code
13:34
uh then we'll see that extra 10%
13:38
uh then we'll see that extra 10%
13:38
uh then we'll see that extra 10% discount
13:40
discount appear cool so just like before they can
13:43
appear cool so just like before they can
13:43
appear cool so just like before they can have complex Logic for each discount to
13:46
have complex Logic for each discount to
13:46
have complex Logic for each discount to say whether it should be on or off or to
13:48
say whether it should be on or off or to
13:48
say whether it should be on or off or to AB test it they can have logic to have
13:52
AB test it they can have logic to have
13:52
AB test it they can have logic to have different percentages depending on which
13:54
different percentages depending on which
13:54
different percentages depending on which users are looking at the discount uh and
13:56
users are looking at the discount uh and
13:56
users are looking at the discount uh and they can use machine learning to
13:58
they can use machine learning to
13:58
they can use machine learning to personalize the copy to each user to
14:00
personalize the copy to each user to
14:00
personalize the copy to each user to maximize the number of upgrades so with
14:03
maximize the number of upgrades so with
14:03
maximize the number of upgrades so with minimal engineering work we've converted
14:06
minimal engineering work we've converted
14:06
minimal engineering work we've converted this simple Boolean feature flag that we
14:09
this simple Boolean feature flag that we
14:09
this simple Boolean feature flag that we had before into this flag which which
14:13
had before into this flag which which
14:13
had before into this flag which which returns a list of discount objects and
14:16
returns a list of discount objects and
14:16
returns a list of discount objects and we've empowered our marketing team with
14:18
we've empowered our marketing team with
14:18
we've empowered our marketing team with this flexible platform to manage
14:20
this flexible platform to manage
14:20
this flexible platform to manage discounts
14:23
themselves now we actually had uh an app
14:26
themselves now we actually had uh an app
14:26
themselves now we actually had uh an app configuration system just like this or
14:28
configuration system just like this or
14:28
configuration system just like this or similar to this
14:29
similar to this uh at meta and it was called uh
14:34
uh at meta and it was called uh
14:34
uh at meta and it was called uh configurator and it was used in a
14:36
configurator and it was used in a
14:36
configurator and it was used in a similar way to
14:40
platformization released a paper on this
14:43
platformization released a paper on this
14:43
platformization released a paper on this called holistic configuration management
14:45
called holistic configuration management
14:45
called holistic configuration management at Facebook and it dives into how
14:47
at Facebook and it dives into how
14:47
at Facebook and it dives into how configurator was used for lots of
14:48
configurator was used for lots of
14:48
configurator was used for lots of different use cases for example it was
14:51
different use cases for example it was
14:51
different use cases for example it was used to configure automated backend jobs
14:55
used to configure automated backend jobs
14:55
used to configure automated backend jobs like user notifications where you can
14:56
like user notifications where you can
14:56
like user notifications where you can configure templates for different
14:58
configure templates for different
14:58
configure templates for different notifications
15:00
notifications types pricing billing and discounts like
15:03
types pricing billing and discounts like
15:03
types pricing billing and discounts like we've just shown in the demo permissions
15:06
we've just shown in the demo permissions
15:06
we've just shown in the demo permissions and features available to
15:09
and features available to
15:09
and features available to users API rate limits inapp copy for
15:13
users API rate limits inapp copy for
15:13
users API rate limits inapp copy for guidance error messages tool tips
15:16
guidance error messages tool tips
15:16
guidance error messages tool tips models forms and
15:18
models forms and wizards metrics health checks and alerts
15:22
wizards metrics health checks and alerts
15:22
wizards metrics health checks and alerts search and ranking
15:25
search and ranking configuration rules policies filters and
15:28
configuration rules policies filters and
15:28
configuration rules policies filters and classification threshold
15:30
classification threshold
15:30
classification threshold machine learning model parameters and
15:32
machine learning model parameters and
15:32
machine learning model parameters and versioning complex rollouts kill
15:34
versioning complex rollouts kill
15:34
versioning complex rollouts kill switches and
15:36
switches and experiments constants API keys and third
15:39
experiments constants API keys and third
15:39
experiments constants API keys and third party integration settings and this
15:41
party integration settings and this
15:41
party integration settings and this large long tail of Niche configuration
15:43
large long tail of Niche configuration
15:43
large long tail of Niche configuration use cases but across all of these
15:46
use cases but across all of these
15:46
use cases but across all of these different use cases we got the same high
15:47
different use cases we got the same high
15:47
different use cases we got the same high level benefits number one we decouple
15:50
level benefits number one we decouple
15:50
level benefits number one we decouple dependencies in our organization so we
15:53
dependencies in our organization so we
15:53
dependencies in our organization so we could enable other teams to selfs serve
15:55
could enable other teams to selfs serve
15:55
could enable other teams to selfs serve and make changes themselves without the
15:57
and make changes themselves without the
15:57
and make changes themselves without the slow back and forth Pro process with
16:00
slow back and forth Pro process with
16:00
slow back and forth Pro process with engineering and as Engineers we could
16:02
engineering and as Engineers we could
16:02
engineering and as Engineers we could focus on shipping code to production
16:04
focus on shipping code to production
16:04
focus on shipping code to production without being blocked by other
16:07
without being blocked by other
16:07
without being blocked by other stakeholders number two we got instant
16:09
stakeholders number two we got instant
16:09
stakeholders number two we got instant updates decoupled from code deployments
16:11
updates decoupled from code deployments
16:11
updates decoupled from code deployments and the release
16:13
and the release cycle number three once we had all of
16:15
cycle number three once we had all of
16:15
cycle number three once we had all of this configuration we could optimize it
16:17
this configuration we could optimize it
16:18
this configuration we could optimize it with hand tuning AB testing and machine
16:21
with hand tuning AB testing and machine
16:21
with hand tuning AB testing and machine learning number four we reduced
16:23
learning number four we reduced
16:23
learning number four we reduced complexity by extracting all this
16:25
complexity by extracting all this
16:25
complexity by extracting all this configuration logic like user specific
16:27
configuration logic like user specific
16:27
configuration logic like user specific code out of different code bases and
16:29
code out of different code bases and
16:29
code out of different code bases and into a single source of Truth and we
16:31
into a single source of Truth and we
16:31
into a single source of Truth and we also got this clean separation of
16:33
also got this clean separation of
16:33
also got this clean separation of concerns between code and configuration
16:36
concerns between code and configuration
16:36
concerns between code and configuration so we could focus on the high level
16:37
so we could focus on the high level
16:37
so we could focus on the high level logic in our code and worry about the
16:40
logic in our code and worry about the
16:40
logic in our code and worry about the configuration details later or delegate
16:43
configuration details later or delegate
16:43
configuration details later or delegate that to another
16:44
that to another stakeholder and number five we got
16:46
stakeholder and number five we got
16:46
stakeholder and number five we got increased flexibility so after writing
16:49
increased flexibility so after writing
16:49
increased flexibility so after writing our code we could configure it in lots
16:50
our code we could configure it in lots
16:50
our code we could configure it in lots of different ways without any extra
16:53
of different ways without any extra
16:53
of different ways without any extra engineering
16:55
engineering work so app configuration is great but
16:58
work so app configuration is great but
16:58
work so app configuration is great but how do we go about building a general
17:00
how do we go about building a general
17:00
how do we go about building a general app configuration system that can scale
17:02
app configuration system that can scale
17:02
app configuration system that can scale to complex use
17:04
to complex use cases the first thing we need is a
17:06
cases the first thing we need is a
17:06
cases the first thing we need is a flexible type system to define the
17:09
flexible type system to define the
17:09
flexible type system to define the inputs going into our system like the
17:11
inputs going into our system like the
17:11
inputs going into our system like the current environment or user and the
17:13
current environment or user and the
17:14
current environment or user and the outputs coming out of our system like
17:16
outputs coming out of our system like
17:16
outputs coming out of our system like the feature Flags or the list of
17:18
the feature Flags or the list of
17:18
the feature Flags or the list of discounts or the list of onboarding
17:21
discounts or the list of onboarding
17:21
discounts or the list of onboarding guides in our
17:23
guides in our app the second thing we need is a
17:25
app the second thing we need is a
17:25
app the second thing we need is a flexible configuration language to
17:27
flexible configuration language to
17:27
flexible configuration language to define the L
17:29
define the L that Maps those inputs to the outputs so
17:32
that Maps those inputs to the outputs so
17:32
that Maps those inputs to the outputs so we should be able to to we should be
17:34
we should be able to to we should be
17:34
we should be able to to we should be able to embed AB tests and machine
17:35
able to embed AB tests and machine
17:35
able to embed AB tests and machine learning loops into our logic too and we
17:38
learning loops into our logic too and we
17:38
learning loops into our logic too and we need a UI for non-technical people to
17:41
need a UI for non-technical people to
17:41
need a UI for non-technical people to edit the logic
17:42
edit the logic visually so when we combine those two
17:44
visually so when we combine those two
17:44
visually so when we combine those two ingredients the flexible type system and
17:47
ingredients the flexible type system and
17:47
ingredients the flexible type system and a flexible visual configuration language
17:50
a flexible visual configuration language
17:50
a flexible visual configuration language we can scale to all of those complex use
17:52
we can scale to all of those complex use
17:52
we can scale to all of those complex use cases that we went through
17:54
cases that we went through
17:54
cases that we went through earlier so this is really powerful but
17:57
earlier so this is really powerful but
17:57
earlier so this is really powerful but it's also a bit scary because we're
17:59
it's also a bit scary because we're
17:59
it's also a bit scary because we're moving critical business logic out of
18:01
moving critical business logic out of
18:02
moving critical business logic out of our codebase and into this configuration
18:04
our codebase and into this configuration
18:04
our codebase and into this configuration system so if the system fails or we make
18:07
system so if the system fails or we make
18:07
system so if the system fails or we make an incorrect change it could cause major
18:09
an incorrect change it could cause major
18:09
an incorrect change it could cause major issues like the one crowd strike
18:11
issues like the one crowd strike
18:11
issues like the one crowd strike experienced recently and we also don't
18:14
experienced recently and we also don't
18:14
experienced recently and we also don't want to impact the performance or
18:16
want to impact the performance or
18:17
want to impact the performance or efficiency of our app by depending on a
18:20
efficiency of our app by depending on a
18:20
efficiency of our app by depending on a configuration
18:22
configuration system so how can we make the
18:24
system so how can we make the
18:24
system so how can we make the configuration system as safe reliable
18:27
configuration system as safe reliable
18:27
configuration system as safe reliable performant and efficient as our own
18:31
performant and efficient as our own
18:31
performant and efficient as our own code first we can design the SDK to
18:34
code first we can design the SDK to
18:34
code first we can design the SDK to locally evaluate our configuration logic
18:37
locally evaluate our configuration logic
18:37
locally evaluate our configuration logic so it fetches all the configuration
18:39
so it fetches all the configuration
18:39
so it fetches all the configuration logic from the server up front in One
18:41
logic from the server up front in One
18:41
logic from the server up front in One initial Network request and then after
18:44
initial Network request and then after
18:44
initial Network request and then after that there's no dependency on the
18:45
that there's no dependency on the
18:45
that there's no dependency on the network to evaluate configuration so
18:48
network to evaluate configuration so
18:48
network to evaluate configuration so it's super reliable performant and
18:53
it's super reliable performant and
18:53
it's super reliable performant and efficient but we still have that one
18:55
efficient but we still have that one
18:55
efficient but we still have that one initial request which could fail so to
18:58
initial request which could fail so to
18:58
initial request which could fail so to make this more
18:59
make this more we can include a snapshot of our
19:01
we can include a snapshot of our
19:01
we can include a snapshot of our configuration logic in our app bundle so
19:04
configuration logic in our app bundle so
19:04
configuration logic in our app bundle so the SDK can use that as a fallback in
19:06
the SDK can use that as a fallback in
19:06
the SDK can use that as a fallback in case it can't initialize from the server
19:09
case it can't initialize from the server
19:09
case it can't initialize from the server and we can also set up a web hook to
19:11
and we can also set up a web hook to
19:11
and we can also set up a web hook to trigger a new build and deploy of our
19:14
trigger a new build and deploy of our
19:14
trigger a new build and deploy of our app whenever the configuration logic
19:16
app whenever the configuration logic
19:16
app whenever the configuration logic changes so we can keep that build time
19:18
changes so we can keep that build time
19:18
changes so we can keep that build time snapshot up to
19:21
snapshot up to date and then if we do that we have that
19:24
date and then if we do that we have that
19:24
date and then if we do that we have that if we have that build time snapshot then
19:25
if we have that build time snapshot then
19:25
if we have that build time snapshot then we don't even need to initialize from
19:27
we don't even need to initialize from
19:27
we don't even need to initialize from the server at all and we can use the SDK
19:30
the server at all and we can use the SDK
19:30
the server at all and we can use the SDK in local only offline mode but then we
19:32
in local only offline mode but then we
19:32
in local only offline mode but then we do lose the benefit of being able to
19:34
do lose the benefit of being able to
19:34
do lose the benefit of being able to update the configuration instantly but
19:37
update the configuration instantly but
19:37
update the configuration instantly but with a blended approach where we
19:40
with a blended approach where we
19:40
with a blended approach where we initialize from the server and we have
19:41
initialize from the server and we have
19:41
initialize from the server and we have the build time snapshot we get the best
19:43
the build time snapshot we get the best
19:43
the build time snapshot we get the best of both
19:46
of both worlds the next thing we can do is that
19:48
worlds the next thing we can do is that
19:48
worlds the next thing we can do is that when we evaluate configuration we can
19:50
when we evaluate configuration we can
19:50
when we evaluate configuration we can also pass hard-coded fullback values for
19:52
also pass hard-coded fullback values for
19:52
also pass hard-coded fullback values for the case when the SDK hasn't initialized
19:55
the case when the SDK hasn't initialized
19:55
the case when the SDK hasn't initialized and when there's no build time snapshot
19:59
and when there's no build time snapshot
19:59
and when there's no build time snapshot and we can also ensure that the
20:00
and we can also ensure that the
20:00
and we can also ensure that the configuration is evaluated with full
20:02
configuration is evaluated with full
20:02
configuration is evaluated with full endtoend typee safety to avoid typos
20:05
endtoend typee safety to avoid typos
20:05
endtoend typee safety to avoid typos catch errors at compile time rather than
20:07
catch errors at compile time rather than
20:07
catch errors at compile time rather than runtime and enable this great developer
20:10
runtime and enable this great developer
20:10
runtime and enable this great developer experience with IDE features like code
20:12
experience with IDE features like code
20:12
experience with IDE features like code completion find all references and js.
20:17
completion find all references and js.
20:17
completion find all references and js. comments and then finally we can Verge
20:19
comments and then finally we can Verge
20:19
comments and then finally we can Verge and control all of our configuration
20:21
and control all of our configuration
20:21
and control all of our configuration logic in a git style history so we can
20:24
logic in a git style history so we can
20:24
logic in a git style history so we can see exactly what changed and when with
20:27
see exactly what changed and when with
20:27
see exactly what changed and when with clean diffs of logic and schema changes
20:31
clean diffs of logic and schema changes
20:31
clean diffs of logic and schema changes and branches the test and preview
20:33
and branches the test and preview
20:33
and branches the test and preview configuration changes before merging
20:35
configuration changes before merging
20:35
configuration changes before merging them into the main branch with a pull
20:37
them into the main branch with a pull
20:37
them into the main branch with a pull request so we manage our configuration
20:39
request so we manage our configuration
20:39
request so we manage our configuration just like we manage our
20:41
just like we manage our
20:41
just like we manage our codebase and we can also layer on team
20:44
codebase and we can also layer on team
20:44
codebase and we can also layer on team roles and permissions to safely onboard
20:46
roles and permissions to safely onboard
20:46
roles and permissions to safely onboard non-technical team members by requiring
20:49
non-technical team members by requiring
20:49
non-technical team members by requiring that all their changes are first
20:50
that all their changes are first
20:50
that all their changes are first reviewed in a pull request so to recap
20:54
reviewed in a pull request so to recap
20:54
reviewed in a pull request so to recap with this local evaluation build time
20:57
with this local evaluation build time
20:57
with this local evaluation build time snapshots type saf
20:59
snapshots type saf and git style Version Control we can get
21:01
and git style Version Control we can get
21:01
and git style Version Control we can get a similar level of safety reliability
21:04
a similar level of safety reliability
21:04
a similar level of safety reliability performance and efficiency as our own
21:09
performance and efficiency as our own
21:09
performance and efficiency as our own code there was no tool out there like
21:11
code there was no tool out there like
21:11
code there was no tool out there like this so we built hypertune and here are
21:13
this so we built hypertune and here are
21:13
this so we built hypertune and here are some links to check us out it's free to
21:16
some links to check us out it's free to
21:16
some links to check us out it's free to get started and the setup takes under 10
21:19
get started and the setup takes under 10
21:19
get started and the setup takes under 10 minutes so why did we decide to work on
21:22
minutes so why did we decide to work on
21:22
minutes so why did we decide to work on this well we believe there's a lot of
21:24
this well we believe there's a lot of
21:24
this well we believe there's a lot of slow back and forth that happens in
21:26
slow back and forth that happens in
21:26
slow back and forth that happens in organizations during software
21:28
organizations during software
21:28
organizations during software development
21:30
development there's a lot of waiting for updates to
21:32
there's a lot of waiting for updates to
21:32
there's a lot of waiting for updates to reach production especially for apps
21:34
reach production especially for apps
21:34
reach production especially for apps where they slow release cycle like
21:35
where they slow release cycle like
21:35
where they slow release cycle like mobile apps there's a lot of lwh hanging
21:39
mobile apps there's a lot of lwh hanging
21:39
mobile apps there's a lot of lwh hanging fruit to improve product conversion
21:41
fruit to improve product conversion
21:41
fruit to improve product conversion rates and the overall efficiency of
21:43
rates and the overall efficiency of
21:43
rates and the overall efficiency of software systems especially as they
21:46
software systems especially as they
21:46
software systems especially as they scale there's a lot of complexity in
21:48
scale there's a lot of complexity in
21:48
scale there's a lot of complexity in those software systems that can be
21:50
those software systems that can be
21:50
those software systems that can be simplified and there's a lot of slow
21:53
simplified and there's a lot of slow
21:53
simplified and there's a lot of slow iteration and we believe that app
21:55
iteration and we believe that app
21:55
iteration and we believe that app configuration when done in the right way
21:57
configuration when done in the right way
21:57
configuration when done in the right way can be the solution to
21:59
can be the solution to
21:59
can be the solution to those
22:00
those problems so thanks for listening hope
22:02
problems so thanks for listening hope
22:02
problems so thanks for listening hope you enjoyed the talk