go back

Product Notifications with Sam Seely, CEO of Knock

podcast image

In this episode, we talk about product notifications–making the right primitives, solutions for advanced features like batching, throttling, and resource-specific preferences. We’re joined by our guest, Sam Seely, Co-Founder and CEO of Knock.

Here on the Yes-code podcast, we talk about hard domain-layer problems and how to solve them. Today we’re talking about product notifications, with someone who knows the domain well–Sam Seeley from Knock.

I’m really excited to have Knock on the show – this is a problem I have had to deal with before, and I’m relieved it exists.

Sam is an expert in product notifications, and Knock is a great example of a Yes-code tool. They solve a high-level domain problem, focusing on one pain point and doing it well. Their end-goal is a beautiful developer experience, which we love.

Relevant links:

Transcript

[00:00:00] John Britton:

Hello, and welcome to The Yes-code Podcast. I'm your host, John Briton, and today we're joined by Sam Seely Co-founder and CEO of Knock, notification infrastructure for developers.

In this episode, we talk about the primitives for building robust product notifications, including solutions for advanced features like batching, throttling, and resource specific preferences.

Let's get into it.

Hey Sam, how are you doing?

[00:00:29] Sam Seely (Knock):

I'm great. Thanks for having me, John.

[00:00:31] John Britton:

Can you please introduce yourself? Who you are, what you do.

[00:00:35] Sam Seely (Knock):

I'm Sam I'm Co-founder and CEO at Knock. We build product notification infrastructure for developers, which basically just means if you're building a product that needs to send product notifications, that could be across email, it could be across in-app surfaces, like feeds and inboxes, push, Slack or Discord integrations, and even SMS, we help you do that much faster and help you scale that system for the long term.

[00:01:03] John Britton:

And when you say product notifications, are you talking about message delivery or something else entirely?

[00:01:08] Sam Seely (Knock):

For most channels we don't handle last mile delivery. If you think about the hard part of delivering notifications 10 years ago, five years ago, it was actual delivery, right? It was how do you get that email into an inbox 99.999% of the time. Now that you have all these APIs from great products like Postmark and SendGrid and Twilio SMS that can own last mile delivery and do that in a really reliable way.

There's a new problem which is not how do you manage delivery? It's how do you manage against over-delivery and actually craft a thoughtful experience as a developer across all these different APIs that you now have to manage. And how do you do that alongside your own in-app surface areas and things like that.

At Knock, we essentially give you the building blocks to assemble that system in a fraction of the time it would take to do so in-house, while still giving you you full visibility into that system and doing some cool things that we can get into later around really delivering a thoughtful experience for users that sends fewer, higher information, notifications.

[00:02:18] John Britton:

I'm a developer. I love programming. I think that programming is one of the most valuable skills that anybody can have. It's a superpower. It lets you take your ideas from just a scratch on a notepad and turn them into a real thing that people can use, with a super high leverage.

And while code is super flexible. I am still frustrated all the time that I have these ideas of things that I want to implement, and I just get sidetracked with building the very low-level fundamental blocks that are necessary for all of these ideas. And so I've started to notice this pattern of really interesting developer tools that solve a specific domain problem with reusable primitives that are very well-defined and hide extreme complexity into a package that's really easy to understand and compose together into a custom solution. And I've been calling that Yes-code. And I think that Knock is a really great example of a tool that follows the Yes-code pattern.

I was motivated by being annoyed by programming. And I wonder, are there any things that are annoying about programming or building software that motivates you.

[00:03:23] Sam Seely (Knock):

I think from my side, and I'm kind of like a weekend programmer, right? I really stumbled upon the problem of Knock from the product side and my co-founder Chris, who was my engineering counterpart at Frame.io. He was the one responsible for building the notification system and so I think we both kind of saw this problem of, exactly what you were saying.

Where like you're ultimately there every day, at a company, because you believe in the mission and you want to be shipping value to customers and like getting things in their hands. We saw not just the notifications, but across a lot of parts of the product stack at Frame.io, where you wish you could move faster in getting to like the final thing that you're trying to deliver to that customer.

And sometimes that's search and you have an experience that you want to deliver for customers, but you get caught up in how you scale indexing and how you'd manage queries and filters on Elasticsearch and how you bring that into a good front end experience.

Algolia came along and solved multiple problems in that stack, but the bundled benefit that you get is you're spending a lot less time at the lower levels of that and thinking more about the final experience that you want to give to users. And that's both from a product standpoint and thinking about what is that faceting experience look like, and it's both just in the backend or infra challenges of how do you scale that and keep it performant and all that kind of stuff.

And so I think for notifications, we started to see it as a very similar problem in our own time at Frame.io, where what you want to be thinking about is how often should users be getting notifications? What types of notifications should we be sending? What should our batching or digesting behavior look like? When should we be not sending notifications on certain channels because they've already been read and in-app experiences and things like that. But often it's very hard to even get up to that level of the conversation because you're figuring out integrations with downstream providers. You're figuring out how the system's just going to scale because notifications are so high volume?

That's one of the things that I was frustrated with in my experience at my last company where you can never even solve those questions that you want to solve for customers because you get so wrapped up in the implementation details and before you know it, it's like, "all right we're beyond the amount of time we can spend on this and we need to like move on to the next thing." And so a lot of the finer touches of that experience end up getting deprioritized not because they're not valuable, but because, there's so much effort required to get to that point.

So I think that's one of the things that I'm most excited about with all these different tools in this kind of "Application-layer as a service" or this Yes-code space is that they enable teams to ship the experiences they want to ship a lot faster and then move on to the next thing knowing that there's going to be a great team focusing on those questions of scale and maintenance and things like that.

[00:06:39] John Britton:

This is something that keeps coming up when I'm talking to people is that concept of like team that keeps working on that space as you go. So it's almost like when you do this, you know, you call it the application, feature as a service. You don't need to be the expert at search you think about the experience, you work on the product level, with a higher-level abstraction and the provider on the other end is constantly enhancing that experience.

[00:07:02] Sam Seely (Knock):

Totally, and I think there are two really cool aspects of that. We saw this as we were using different tools at Frame.io or even just exploring those services. Stripe is a great example, right? If you're doing payments in house best case scenario you're, you know, you maybe have a squad of five people dedicated to that but you're not going to have, and maybe as you become a really big company you get up to like 30 or 50 people working on that problem alone but you're never going to have the like singular focus on payments that Stripe has. You're never going to have a team of some of the best designers and product thinkers and developers in the world focusing on that problem and that problem alone and you can just kind of see how that product's evolved from the initial payments API up into, you know, some of these application layer things like Checkout and all those experiences that are just plug and play now.

So that's the first thing, right? Is you just get this great team and their entire reason for existence is this one problem and so they're going to be able to obsess over it to a degree that would just never make sense financially or focus-wise for an in-house team.

But second, there's this other really cool kind of point of leverage that these services give to their customers, which is that when Stripe builds payments, they're not just doing it for one customer. There's this horizontal service that is giving it to many customers. Over time, you see that have all these cool benefits that you couldn't really see up front where like, oh, they have massive volume going through that system so they can do things like Radar and other product offerings that you can really only do at that type of scale. The Facebooks and those like giant consumer services of the world have the type of scale to be able to do that in house but even growth stage companies don't really.

And so I think that's the other point of leverage is, it isn't just time and focus, but it's this volume feature stuff that starts to bubble up that customers then get the benefits of without even having to spend any time on that kind of work.

[00:09:13] John Britton:

And they would never reach that scale anyways, right?

[00:09:15] Sam Seely (Knock):

Yeah, ex-exactly.

[00:09:17] John Britton:

You mentioned Radar, which if, if folks don't know what it is with Stripe, you have this ability to detect potentially fraudulent charges and the way that they detect it with the service is based off of all the data that they have from all of their merchants.

And so you if you were just using your own data for that kind of a feature it's just infeasible and so you get those kinds of advantages as well.

This really is just a case of, from the economic speak, comparative advantage playing out. We focus on the thing that we're really good at and build a very good toolset for that space and then others can benefit from it and hand that off. I really love it.

I know Knock is notifications infrastructure for developers. Can you give me some context about what makes notifications so hard? We already kind of talked about it a little bit with it being too much, being much more than just delivery, which is kind of like a problem that was solved some years ago, let's say, and now there's these new problems, but what, what are those problems and why are they so hard to solve ourselves?

[00:10:14] Sam Seely (Knock):

Once you have delivery solved and you can make a single API call to SendGrid and know that it's always going to get that email to your end user. Now you're dealing with this problem that abstracts on top of all those platform APIs that are managing delivery on your behalf.

So the first problem is just are you delivering an experience where let's say you can reach them across email, SMS, push, and they also have a Slack integration that they've enabled in your product. I think the default behavior that you tend to see is just treating it like a simple routing service where like event happens, you build the notification template, and then it's just going to go out to all of those. But if you're an end user of any B2B software, let alone anything on the consumer side that gets very annoying as a user to be going through all the different inbox experiences you have on all these different clients and reading the same thing again and again and again.

People are starting to think about is there more thoughtful experience that drives better user engagement and ultimately like better long-term user retention. That's the first thing is as you're looking across all these different services, what's the sort of logic engine look like that's going to figure out when you send across which of those channels.

Then there's the whole question of building the in-app notifications experience that is going to live alongside all these external platform APIs that you're calling. The classic example of that is the in-app notifications feed, the little bell that you usually see in the navbar of applications that lights up with a badge when you need to go look at something or you need to complete some action.

Designing that experience, building the front end components, which means everything from filtering that list, paginating it, being able to archive notifications, being able to update badge counts in real time. There's that whole build-out plus the backend models that are going to be managing per tenant per user state. And that's sort of an expansion of scope of you're no longer just routing events that happen in your product to these different platform APIs, you're now actually keeping per user state around and reacting to it and doing things like "have they seen these items," "Have they read these items?" So that in itself is a big effort to build out and then maintain.

As you get deeper into high volume notification system a collaboration tool is like a classic example of this, where you start to realize that "hey, someone's commenting in this document or on this video or on this image." And as usually happens when you get into flow state, you're probably leaving a lot of feedback, right?

In the span of 10 or 20 minutes, you might leave 30 comments in some cases. What that looks like by default for a lot of users is 30 separate emails showing up in your inbox. So being able to batch those, not on like a simple Cron job basis where you're basically looking for this stuff every hour and then batching it up for users, but actually doing it on a, "Hey, this event just happened, open up a window, listen for any subsequent events." That's a really difficult thing to build out and get right for users. That's one of the things that we see a lot of our customers coming to Knock for today are these building blocks, like batching, like throttling that give you these kind of hard to build backend concepts and let you use them instantly in your notification system.

There's all those pieces around managing delivery across many platform APIs, figuring out how to do that alongside these in-app experiences. Then introducing these logical blocks, like batching and delays and throttles. And then there's just the problem of how do you have visibility into this system over time as your product grows and you introduce more types of notifications as you ship new features.

After that initial build, what you tend to see is all of this just lives in backend code, right? So if you want to update a notification template, if your product manager wants to understand in what cases certain notifications send, it's basically a, you know, roadmap item or a ticket in your issue management system of choice to go and look at this and parrot it back to the PM and give them visibility into that. Or I've done, many of these. Every six months or 12 months, you just go through the product and try to trigger every notification you can and just keep a spreadsheet inventory of all the notifications we are pretty sure the product is sending.

There's always like that little feature that was spun up in a week and the first year of the company and, you know, some users are kind of using it. As a product grows over three, five plus years, understanding how that system is working is a tough problem and most teams don't have the bandwidth to build out the internal tooling and dashboards that problem like really demands. That's the second higher category problem is one just building it, two maintaining it and iterating on it.

The third problem is just that scaling notification systems is very challenging. If you think about what a notification system looks like it's like a very high write high cardinality type of system where that single event happens in your product. Let's say it's a comment on some page. That will be fanning out to N number of followers on that page, each of who is receiving that on however many channels that they are registered for notifications on. So you can quickly see how like the pace of notification volume growth accelerates faster than all the activity that's happening in your application. We saw this in multiple startups where the conversation about rebuilding the notification system for that next stage of scale always felt like it was happening earlier than we thought it would.

When you have a lot of like core product to go focus on and build, and then you're suddenly staring down like a three month rebuild of the notification system because users are getting spammed or you're dropping messages. That's a really difficult decision to make. I think the important like thing to underline here is notifications are a critical part of these systems.

If you start to drop invite emails to new users you will very quickly see that show up in user signups and ultimately in revenue. Right? So it's usually, if you get to the point where it's starting to outstrip the capabilities of your current system. It's not really something you can ignore.

[00:17:25] John Britton:

It's really interesting with notifications just as the problem domain, because in a lot of ways, as a developer or someone working on a product, it feels like a feature that's secondary and in support of the main use case of your product, but it is incredibly valuable and important because notifications in a lot of cases drive user engagement. How do I know to go look at that pull request that my coworker just made? Because I got a notification for it. Why do I have the notifications enabled? Because I know that I'm only going to get the notifications that I want to get, and they're going to be timely and useful and all of those kinds of qualities.

And if you can't deliver an experience like that, it's table stakes to be able to deliver that kind of experience, then you're just not going to have the same kind of user engagement either.

[00:18:10] Sam Seely (Knock):

Exactly. With notifications too, words like "engagement", there's kind of this, I I don't know if "pallor" is the right word, but this kind of idea of like, like we're all end-users of these apps. And I think there's a lot of notification fatigue out there. Even when you're building notifications, it's not always the most exciting thing to build.

And I think a lot of that comes from the fact that it's very hard to get to a thoughtful experience where you feel like you're not just, like, hitting up users for engagement but actually like thoughtfully driving value, right? And I think in B2B apps especially these aren't products where users can just opt out of notifications.

If they have to approve new credit card issuings or approve new seats that are being added to a product, it's the kind of thing that you need to keep around. Thinking about it through this lens of delivering user value and knowing that sometimes it's valuable to not send a notification or it's valuable to, to batch it together with other things that are happening in the app so that, it's not a volume game.

It's not trying to growth hack engagement. It's trying to work from this place of what's in the best interest of our users to make sure that they stay with the product for a long time and get the value out of it that they came to it for.

[00:19:30] John Britton:

Yeah. When I was looking through your site earlier, I actually noticed in your documentation that there was a clear delineation between product notifications and marketing notifications or user engagement notifications. And I think that this is a really interesting segue into the question of what's in and what's out with Knock and how do you decide what's in and what's out, with the product, with the architecture of the system and whatnot?

We've all been in that situation. We, we go to work and we use some issue tracker or we use some kind of collaboration tool, like a chat system, and we can't turn notifications off, but we need it to be an experience that is valuable.

So how do you decide what's in and what's out with Knock?

[00:20:07] Sam Seely (Knock):

I'll answer that on two planes.

The first you mentioned is marketing versus product notifications. I'll answer that and then second get into like within product notifications how do we think about what lives within the realm of Knock and what lives within our customers' applications.

On the marketing side, we looked at, if you think about any company and the messaging that they send to customers you can basically split it down the middle between marketing notifications and the type of things that the growth team is sending to drive top of funnel engagement and really get people to that sign-up event.

And then there are the, historically they've been called transactional notifications some people call them product notifications, where you are now a user in that product and the events of either the product itself or users that you work with in that product are driving notifications that you receive.

We kind of looked at that whole space and really felt like, okay, the problem that we felt here is it's product notifications. It's not final delivery but "how do you build a thoughtful orchestration layer on top of that?" "How do you build preferences into that?" "What about all the in-app messaging that accompanies that system?"

With marketing notifications, it felt like that was a problem that had been solved for marketers, right? There are a bunch of great tools out there. If you're looking to power customer journeys through your funnel tools like Braize, Customer.io, Leanplum.

What we saw was those tools support some transactional messaging, but if you're a developer relying on those APIs to power batched comment notifications, or you need to build an in-app feed to power, those types of experiences, you're basically left building all of those backend blocks on top of those APIs. Right? And so we really felt that product notifications was kind of an underserved part of this market where none of those tools are really solving the root problem for developers and product people, which is the actual backend system, that's living on top of these APIs.

So that's where we draw the line between what we focus on which is just product notifications. It's just transactional notifications.

[00:22:32] John Britton:

Which in itself is a huge problem. There's no shortage of things to solve in that space. You know, The more I talk to people behind these kinds of developer tools, the more I'm seeing a very well-defined problem space, that's one particular segment of how it's done.

[00:22:46] Sam Seely (Knock):

Yeah, exactly. And then I think within that space, as we dug into product notifications and thought about the best way to really deliver that service, you start to find the lines of what problems you handle as a developer tool versus what problems will stay within the domain of the customer.

The way we've thought about that, is Knock should handle the parts of notification services that in their component pieces are, are, generally used across all applications. And then second, we aim to like reduce redundancy between our system and our customers, so, like, if there's logic that is going to have to live in your app, no matter what, then it doesn't make sense for you to have to like mirror that into Knock just for our use case as well.

A few examples of that, preferences, if you look across a lot of different apps and look at the types of notification preferences that they offered it to users, there's no cookie cutter single front end component that would work for all of those, right? They all use some different combination of preferences that you can manage at a channel level, meaning, "Hey, opt me out of email. I don't want any email from your service." Or they might do that at a notification type level, meaning, "okay, I want to be notified about mentions, but not general activity that's happening in the app." Or they might do it in some cross hatch of those different categories.

So it might be "okay for email, I want these types of notifications, but for in-app I want all of them because they're not as intrusive." So that's the type of system that at first you look at and it's oh, that's pretty custom across all these apps, but then you see that the component parts of that will always look the same.

Meaning. If you can give developers a flexible way to manage preferences by channel, by notification type, by category of notification, and flexibly define that as they want then that's kind of the component that they need, and what they don't want to handle is all of the logic that decides for a given recipient and their preferences, you know, how, how to notifications get sent. And so that's the point of abstraction that we've defined for developers to work with Knock preferences. And if you go check out the API, that's what you'd see and what we own for customers versus like what we let them define, versus giving them one table view that you just inflexibly are forced to work with.

There's another example, retry logic for downstream services. Meaning, you call SendGrid for some reason, it 400s, or you get some other type of error, and we need to retry until it sends and we back off exponentially as we continue to retry that service, that's something that every notification system should have. But it will always look the same for all customers. That's a part that very squarely lives within Knock and that our customers don't even have to think about.

You know what the error response is that comes from one of those, services, but lives like squarely within the realm of things that we obsess about and do for our customers that they don't really need to even think about within the kind of fence of their application. They have like complete debugger visibility into that, exchange, if they'd like to check it out or if they'd like to see.

And then, on the opposite side of that, you get things like who to notify when something happens in your app so in that example earlier, we talked about leaving a comment on a page and all of the followers of that page should get notified. Well, that relation of which users in your app follow that page. That's a core data of your product, right? It's how users relate into page resources in this case.

So that's a piece that our customers still manage, and then when they call Knock, they are essentially telling us a comment happened and here are the recipients that should be notified. And so that's an example of what our customers still manage. And then what we handle for them is running through the notification logic for that given event for each of those recipients.

That kind of gives a sense of like, where the handoff goes from, like our customer and their data model to the data model of Knock and of notifications that we manage on their behalf.

[00:27:25] John Britton:

That's something that I think is really important with these kinds of tools, developer experiences, is drawing the lines in the abstraction in a way that's convenient for the developer. I've worked with a lot of tools where I find myself repeating myself over and over again, just because the way the system was designed, I have to provide the same data every single time, or I have to duplicate something in the other system.

So your case of, you know, what's part of the user's domain model versus what's part of ours and what can we, what can we intelligently hide, is really valuable and I can definitely see the case for, no matter what, in my app, if I have a concept of users following a post or users following some kind of a project that's going to be in my data model, no matter what, and not needing to replicate that in a separate system seems pretty valuable and also gives you the flexibility to like, define that over time.

Right? You don't have to like keep data synced and so on and so forth.

[00:28:16] Sam Seely (Knock):

It's the type of data that like you want ultimate flexibility on, right? As you add, like new parts to your model, and as you like, understand. Like where the product's going to go. That will look different across all products, both within like kind of collaboration and productivity, but also within, you know, like marketplaces and consumer products. That's the type of model that like no customer wants to have to like continue to update and downstream providers.

[00:28:45] John Britton:

I'm a developer, I'm building an application and in many cases, you know, applications can really benefit from having a notification system. And this is classically like one of those problems where it's like, It's not really the core functionality of my product, and I don't want to think about it right now.

And one of the ways to help is to have a really, really, really easy onboarding experience for users. And I wanted to ask you about kind of the first run experience. If I'm a developer building product notifications into my existing application, what does it look like on day one to build product notificiations with Knock and how did you design that? What were the kind of values you were thinking about when you were designing that experience?

[00:29:23] Sam Seely (Knock):

We're kind of two parts to it, but the guiding light through all of this was just getting you to that first notification sent as quickly as possible. And just kind of showing you the key building blocks of the system that you have to interact with. And I think as you solve, more needs for more customers and you learn more about what building blocks you need within, any type of system that like solves a problem for developers at this part of the stack.

These products get more advanced and you can see it in some of the ones that have been around for a while. Like there was a lot of capabilities, in like the Algolia API or like the Nylas, API docs. Right. There's a lot there. And so I think one of the things we really wanted to emphasize was sort of like progressive discovery of complexity and like power the system and only giving you like the basics that you absolutely need upfront.

And then as you discover these like other use cases, Then, you learn those parts of the API docs and, you do that on like a strong foundation of the essential concepts of, of Knock. So when you jump into our docs, one of the first things is you'll see, is our "Get Started Guide", which runs you through five enumerated steps to get that first notification sent in Knock.

And that's set up a channel. You have to have at least one channel to be able to send a notification to.

It's building out your first workflow. Workflow in Knock is basically a notification type, right? It's some trigger happens and in the simplest workflow, you're just sending it to one channel, but over time, those become more and more complex.

And then it's triggering that notification and notifying the recipient that you're specifying on that workflow and that's, that's pretty much it and so if all you're looking to do is just send that first, notification, those are kind of the steps to do so.

Then, like the next thing we introduce you to in the documentation is like, what are these key data concepts, these key parts of the Knock model that you want to be well-versed in as you just think about, moving beyond that initial. "Hello world" notification and moving into like, okay, well what's the system we'll want to build right now.

And what do we want to do in a few months or in a year or two from now? And, how does Knock help us get there? Right. And so that's where they go into the documentation. They can read about the preferences model and understand how to do that. They can, read into our objects model and it, how it powers non-user notifications like Slack channels and things like that.

Those are all things where like, even preferences, if you're starting like a side project or you're just kind of getting your product live in production, you might just be sending a welcome email. So, even preferences, which is one of these like essential parts of a notification system. It's not something you do until you start adding of the notifications beyond like the welcome email, which you'll send once and, you know, forgotten password emails. If you happen to be using password based auth.

[00:32:39] John Britton:

Going down the same path is I'm a developer. I'm building this thing. I want to add notifications. The obvious choice for me is build it myself or use something else and so in this build versus buy decision tree, do you have any opinions, recommendations for people around when is the time to start considering using a third-party service for something like this.

I can build my own welcome email, no problem. But what are the trade offs of, you know, starting with a DIY system and switching later? Where do you see most of your customers making the switch? If they're not starting with you from day one?

[00:33:12] Sam Seely (Knock):

The case of that simple welcome email, or the simple forgotten password email, those are cases where if you're just building one or two templates, within a single channel, such as email, where you're only going to be calling one of these long standing platform APIs with a very simple single player use case, like a welcome email, then you're probably good to just build it in house, you know, in a couple hours very quickly and just move on to the next thing you need to do.

If you want to start from Knock on day one. Great, but, don't have to. I think where we see a lot of people, and that's reflected in the customers that come to Knock, is almost all of them are already sending that simple welcome email themselves because the moment you ship a product to users, you're at least sending one or two of those.

So a lot of customers come to Knock with that already in place. They come to Knock because they either like stumble upon a use case that requires a like higher cost to build channel.

In-app feeds is such a great example of that, where building out an in-app feed, even like an early V1 of it, you're talking at least like a sprint to two sprints, two to four weeks, which is, even that is a pretty ambitious timeline. Whereas Knock customers get in-app feeds live in production in under an hour, it's just dropping in, we have a open source React component, that folks can just drop in, or if they have a component they've already designed and built, they can just plug it into our feed API.

Slack is another one where digging into the docs of Slack and figuring out how you're going to, not just like OAuth into those types of services, but manage the state that you get back from them. And, how do you kind of model things in your product into Slack channels or Slack user DMs and things like that.

[00:35:09] John Britton:

And then you've got like multitenancy and each customer has their own Slack. You know, it gets complex pretty quick.

[00:35:15] Sam Seely (Knock):

It gets, yeah, and that's the type of ramp in complexity where teams, start to look for a third-party service instead of building it in house. The other ramp you see is where there's more complexity starting to creep in, the moment you start fanning out to multiple channels, you start to deal with state aware notifications, Should we be sending this email or this push notification, if the in-app message has already been read? Once you start trying to solve those types of problems, it's a good time to take a look at Knock. Or, we talked about batching earlier. That's another like great case where instead of building out all the models for managing groups of events that, start at a specific point in time. Knock basically gives you that as like a building block that you can add to your workflows in like a minute. Those are the types of like ramps and complexity that usually make it at least worth thinking about, you know, buying versus building in-house.

[00:36:12] John Britton:

I want to talk a little bit about architecture and system design and you did kind of already start to tell me a little bit about some of the primitives you exposed to Knock, especially those ones that are part of the onboarding, the most fundamental primitives in the system.

Could you potentially give us a kind of high level overview of, "Hey, I'm a developer, maybe I didn't read the docs yet," I have, but you know, I'm asking you for, for the sake of the audience, to just kind of give me like an architectural overview of "here are the things you need to understand. Here are the main kind of, building blocks you're playing with and what you should know as a developer coming to Knock for the first time."

[00:36:47] Sam Seely (Knock):

The first thing is Channels. So we have you know know have a set of pre-built channel integrations where you're essentially just like, configuring them with the API key of these downstream providers, and any other like config options that you might have in place.

[00:37:02] John Britton:

So this is like email, push, chat messages.

[00:37:06] Sam Seely (Knock):

Exactly. It's email, push, SMS, third-party chat apps like Discord and Teams and Slack and then the fifth channel type is just like in-app messaging in general, which is all powered, out of the box by Knock So that's the one, one channel where you still configure it in Knock, but

[00:37:24] John Britton:

Right, it's actually delivered by Knock.

[00:37:26] Sam Seely (Knock):

Exactly, yeah. So that's the first kind of concept. And I guess it's kind of an obvious one, but it's Channels.

The second is, Users. With users, you're either, you know, storing users in Knock, so that we know, you know, when you send across a user ID in a notify call, and I'll explain what that means in a second, but basically we, we need to have user data to know which email address to notify a user, which phone number to send them a text, that type of thing.

Or if we're sending them a DM in Slack, we need to have the channel ID on which to do that. Currently we're working on, an API extension, you'll actually be able to pass user data inline. So the concepts of Users is always there and we're bringing some flexibility into whether you want to keep it in Knock or whether you just kind of pass it through at the time.

[00:38:16] John Britton:

At the time of the notify call?

[00:38:17] Sam Seely (Knock):

Exactly, yeah.

So then you have Channels, you'll be notifying Users across those Channels and the way you tie those together is through Workflows. So Workflows is just, you trigger a Workflow through what we call a notify call, that goes through any number of, kind of channels that you're configuring within that workflow.

And then that's also where we bring in the idea of Functions. The Functions, we power in Knock, batching, delays, throttling, we have a bunch of other cool ones coming too, which I can get to later. You use those functions throughout your workflow to basically kind of build the, build the experience that you want for that given type of, of notification.

[00:39:01] John Britton:

And in those Functions who is configuring and running those, is that the developer's job in code, or is that something that, you know, a product person on the team can use through like an admin UI?

[00:39:14] Sam Seely (Knock):

Yeah, it's, it's flexible. So in some cases, we'll see, teams, just setting a kind of standard, like for batching, right? They'll just say, "Hey for comments, uh, batch it every hour. So the moment a user starts commenting on a page and some recipient is going to be notified about that thing, you know, listen for an hour and then at the end of that, if no more events are coming through, then, you know, send it off in a batch.

That's something that a developer or, a product stakeholder could configure in Knock, but we also let you do what are called, dynamic batch windows. So maybe you want to set a user property like a preference where users can decide, "Hey, I want to be notified on these types of batches or digests hourly or daily or weekly." And you can set that as a user property and then reference that, in the batch window, or

[00:40:05] John Britton:

So you could have multiple followers of a particular kind of event where like, John for example gets an hourly batch, but somebody else gets on the like, no, no delay whatsoever just every single comment.

[00:40:16] Sam Seely (Knock):

Exactly yeah.

[00:40:17] John Britton:

Oh wow. That's pretty cool.

[00:40:18] Sam Seely (Knock):

Or like, another great example of this is like for task management type of use cases, you get like due dates in the future that you tend to want to like remind people about, a day in advance or three days in advance. So that's the type of thing where you can generate like a future timestamp, or point in time for, you know, not just that specific user, but that specific event or task and do that dynamically. So there's actually a, and these are all like pieces of flexibility we've introduced as like real developers have used Knock for real life use cases. And you like, it's one of the cool things about working on a developer tool is once people start to use it, you get a lot of feedback very quick, very quickly.

Hopefully if they're listening they'd agree that we've been moving quickly to ship it to them, but that's a lot of the, like, flexibility that we've introduced as we've heard the need from, from customers. And it's powering a lot of like varied and cool use cases today. So, that's a long answer to your question, but that's kind of what it looks like for functions.

[00:41:25] John Britton:

So we've got Channel, Users, Workflow, inside of Workflows we've got some Functions: batching, delays, throttling, some more to come in the future.

[00:41:32] Sam Seely (Knock):

Yep

[00:41:32] John Britton:

Any other primitives that we should know about?

[00:41:34] Sam Seely (Knock):

Yeah. So the other ones are: Preferences are a big one, right? Preferences basically give you like and preferences can go deep, but they basically give you like a per user, data structure for storing, either like a preference per Workflow, a preference per Channel. And those are both we've already talked about.

You can categorize workflows if you want to say, like, offer a preference about all kind of admin type notifications or a preference for all, like if you look at, Linear, which is a tool we like to, uh, fanboy about a lot at Knock, they offer like high-level categories around like all issue updates. So if you just want to opt out of all issue updates, you can in a click, instead of going through all eight individual notification types. We also give you "Preference Conditions" which can power things like, "hey, I want to mute this specific page because you know, someone's getting a little overzealous on their feedback," or something like that. Even down to like per resource muting, you can handle with our preferences model, which is pretty cool.

And then the last, like key data concept is Objects. Objects is something we introduced right around the time we introduced Slack notifications where you learn that, you're not always notifying a user with a notification system. Sometimes you'll have a, let's say like a project in your product and that project and everything contained within it and all the pages and you know files and things like that. Maps to a single Slack channel that your team has joined.

And so in those cases, you're not actually notifying those individual users directly, you're tying like that Slack channel ID to this kind of resource in your model and we help you do that with, with Objects and they unlock some other cool use cases. Like putting notification feeds on specific resources in your system, like projects and pages.

[00:43:38] John Britton:

I'd love to know what, from your professional experience or, other systems you've worked with was inspiration for this. Were there like specific situations where you're building things in the past that were challenging, that that really fed into this design that you ended up choosing, like what, what was the source of this inspiration for this approach to the problem?

[00:43:57] Sam Seely (Knock):

A lot of it came from just our own experiences building SaaS apps and collaboration apps, and, , Chris, my co-founder has worked at a lot, I've been Primarily in B2B land, and he's worked on a lot of other stuff too. We really started Knock from day one with a lens on like, what, what are the problems we would have needed to solve in those past seats and like, what are the primitives we wish we had our disposal.

The batch function is a great example of that, because if you've built a collaboration app that starts to see strong, like user engagement and adoption, very quickly, you start to hear from people about way too many notifications. At Frame.io are, like, biggest detractor feedback we heard from users was that we were sending them way too many notifications and as we dug into it, we realized it was because of, how we were kind of batching these like comment notifications. So that's an example of where we kind of saw this like user problem that we wanted to help all of our customers solve for.

And that's kind of what led us to, to some of these insights about the types of things that, that we would need. And then a lot of it just comes from, like I mentioned earlier, a lot of customer and developer feedback. You know, We use Knock power knock, which gets kind of Inception-y and meta-y and weird.

In doing that, you learn about, what parts of the API design work really well, what parts feel superfluous, what parts you need to introduce, what like key parts of the model it's missing and then you even like figure out kind of what sorts of developer tooling you want on top of that base model.

Very quickly as we were using Knock to power our own notifications, we realized you need full visibility into this system, right? From the request of that notify call down into like the step-by-step execution of a Workflow and what errors are being tripped, if any, down to the, exchange that's happening with the platform APIs for any of these Channels you're working with.

And so we invested a lot of time upfront in our debugger experience and making sure that developers using Knock have the same, if not better, observability into Knock than they'd have if they were building a system in, in-house. So that's a little bit of how we thought about kind of the API design as well as like the auxiliary tooling on top of it.

[00:46:34] John Britton:

You can't overstate how valuable that observability is. And that's one of those things that it ends up being an internal tool you have to build that's totally, you know, it's, it's necessary, but it's totally outside of the scope of your normal work and it's just having that there from day one for you is like the best thing. It's so helpful.

[00:46:55] Sam Seely (Knock):

It's like having, not used Knock in past roles cause it didn't exist yet and using it now at Knock, obviously I'm hugely biased, but, um, I'm very glad we have it. And we talked earlier about like, where you get frustrated in a world, like before these tools exist. And I think that's like a great one, right?

Where very, very rarely is a team going to make the prioritization decision to be like, should we build that internal dashboard so that we have best in class observability and visibility into the notifications we send, I've not met a team, that's decided to do that in-house.

[00:47:34] John Britton:

They're not wrong, they're not wrong to do that either. That's not the best way to spend their time.

[00:47:38] Sam Seely (Knock):

Definitely not. And I, I know that from experience when we decided not to do that at my last company. But it's the kind of thing that, you know, it kind of leaves that pit in your stomach where like, we made the right decision not to do that, but I really wish we had it because people are reaching out and like, we have to open support tickets all the time, so people can look in and like, see why wasn't that notification sent to this enterprise customer. They're not getting invite emails or whatever it might be. And so, it's the type of thing that you wouldn't prioritize in-house for, which makes sense. You're like a high growth startup. You've got a lot to do on the core product, but it's one of those benefits that is like really nice to have in these third party systems.

It's why you see it across all these different types of services. It's this window into service that they're, that they're offering for you.

[00:48:28] John Britton:

I mean real talk, you know what we're actually doing when we don't build these tools is we're just command line into production to debug, you know, line by line what's happening in a real request, which is like a terrible pattern to do. But. Most places do that.

And we even had at a company I used to work with, we had a support rotation. So one engineer off the engineering team would join the support team for a week at a time and their job was to take any support escalations and basically log in to the production command line, to like fix data problems or debug an issue. And then ultimately work on tickets that were based off of, you know, what the highest support load things were.

But it all came down to a lack of observability and the support team couldn't even look at this stuff because the only way to get to it was a production CLI. So that's a huge, huge win to get that without having to build it yourself.

I wanted to ask you, among your users, were there any, people who adopted Knock and did something you totally didn't expect and, found use cases that surprised you.

[00:49:28] Sam Seely (Knock):

Yeah, definitely. I think when we started Knock, we always knew like any product with some amount of complexity and notifications is going to want to use Knock. Our initial, like target segment was very much B2B SaaS and kind of productivity and workflow software, partly because it was what we knew, but partly because we knew that's where there was a lot of notifications complexity. We've seen like since then a lot of marketplaces, have kind of found Knock inbound, because in a marketplace you think about, you have some supply side of that marketplace that's usually trying to get some type of quote fulfilled, or they have like some service that they're seeking.

And then you have the other side of that marketplace. That's responding to that and hopefully delivering value back to the person that opened that in the first case. Seeing, those types of customers use Knock, and use it as much as they do, we're talking teams where they have, you know, 50, 60, 70 plus different types of notifications that they send with Knock.

That's been surprising to me because coming from the world, I came from you'd expect kind of 20 to 30 different types of notifications. But in these types of like marketplaces or high friction, transactional workflows there's so many little pieces of, you know, how a like quote gets opened and someone responds to it and the service is finally delivered and all of that, that goes into that.

Having that all in Knock and giving that visibility into it has been validating, but then also like a surprise to see that, that kind of much stuff happening in it. I think the other thing that's been cool is in our in-app experiences we initially just started with this in-app feed and that's really the kind of scope of in-app notifications that we had in our minds.

A lot of our customers just use the in-app component out of the box and they just kind of drop it in and, style it to look like the rest of their app and then they're onto the next thing. But they can build like custom components that interface with our feed API to power, other types of experiences, and some use that for feeds, but we've seen a lot of customers use that for like full page inboxes for like task management and those types of use cases because really what, uh, in-app notifications are, is there, you know, per tenant, per user scoped, things that that user needs to know about, and that, that user's acting upon. And so seeing, like, customers take, the like underlying kind of API that powers the feed and saying, well, no, we want to reorient all this stuff in this way or we want to present this as like a tabbed kind of task management center has been, uh, has been super cool and not quite something that we've expected. And then the last thing would just be all the kind of extensibility we've seen around Functions and powering that dynamically via the API, which we talked about a little earlier.

[00:52:34] John Britton:

What doesn't Knock do right now in the notification space? I'm sure there's a lot of things that you're, you're hoping to, or you're planning to build in the future, and what's kind of highest on your priority list going forward if you're willing to talk about that?

[00:52:47] Sam Seely (Knock):

I can mention a few things that we're excited about that are, coming down the roadmap. So one is, if you think about like what type of data Knock has, part of that is like understanding how many, notifications a given recipient has received over the course of some window of time.

As we think about what sorts of Functions or logic you want to introduce into a workflow we want to start bringing in sort of like a query layer into that where you can, and this was actually, I won't take credit for this, it was, a customer we're talking to, it's basically the ability to say, "Hey, for this batch, you know, send it, after this window of time, but only if the recipient hasn't received over a certain threshold of messages, in like the day prior.

And so they're basically doing this kind of cool self-referential, logic around look at the data for that, that recipient in Knock, look at what type of message volume they've received, and make a decision about sending it to that recipient, based on that volume. Which I think is a super cool to see, like, people pulling these kinds of new tools out of our team to send better experiences that are going to deliver a better experience, that will mean fewer notifications for recipients.

So that's one, the other is today, like every Knock Workflow is powered by an API call. Right. Um, so you can kind of think of it as a single source system. We want to change that. So, uh, later this year, we'll be introducing additional sources.

So if you think about like popular CDPs, like Segment, or even like reverse ETL tools, the goal will be that you can basically take those kind of event streams and channel them into Knock and then basically say like, "Hey, if we hear this event, trigger this workflow," or " add some conditional logic into this workflow if this event is received." So you'll be able to power like more and more things with Knock and that'll also help more customers get started, or even product stakeholders get started building workflows without needing engineers to call the API directly.

[00:55:04] John Britton:

Are you thinking about including things like event buses? So for example, say I have a, what do you call it, like a microservices architecture and I already have an event bus within my system and I'm sending tons of events. Can I add, in the future, potentially add, Knock as a, as a recipient on that bus and then automatically get some free notifications out of it, or mostly free?

[00:55:22] Sam Seely (Knock):

The goal is that any event stream you should eventually be able to bring into Knock, because that's really what Knock is, it's a product engagement, product messaging engine, where like the source data is an event stream and then the output is like messages to any, you know, down-stream services.

[00:55:41] John Britton:

With the API as the main source of the events right now, that's, it's basically just like REST API calls. So, whoever's using Knock. The developer is probably writing some kind of background queue that sends you know API calls reliably or something to your system. Right?

[00:55:58] Sam Seely (Knock):

Yeah.

We're also gonna look at where you don't have an event based use case for notifications. You have, well, it may still be like event triggered, but in some cases you want to query across like a broader set of data and understand, "Hey, for the like 10 pages that this user is following, it's the end of the week, join those pages with the comments table, and understand what are the five comments that this user really needs to see?" And, you know, there's some of that you can do through like event based systems like this, but I think we're also going to be exploring like ways to query that data, you know, with SQL at the outset of a workflow.

So you'd be able to like, build like the data set that you're going to use across all your notification templates with, you know, build that data set with a SQL query and then run it through the engine as you would like with any events. So those are some of the ways that we're thinking about what additional sources come into Knock.

And then long-term our goal is to be able to, we talked at the start of this conversation about some of the benefits you can provide as a horizontal, like provider to all these different services and what that scale gives you. And so, you know, we've spoken to teams at Facebook and Airbnb and Pinterest about the in-house systems that they've built and how at their scale they can provide recommendations or prioritization algorithmically on what sorts of notifications can be sent.

And we'll like be exploring ways to unlock that for our customers. So to start, that could just be things like understanding a user's time zone and whether a notification should be sent in the wee hours in the morning, or, and as it gets more sophisticated, trying to just help our customers power more like thoughtful experiences in how they, how they message their own customers. So that's, long-term what, we're what we're moving towards and what we're excited about.

[00:57:56] John Britton:

Thanks so much for sharing the, uh, the plans and ideas that you're thinking about. My reaction to this is just, as you say it, each one of these features, I have this kind of combination of, "wow, that's really awesome and it seems very simple," but then the developer in me, just kind of cringes at the fact that like to build that is such a huge pain and, uh, you know, the, the idea of potentially, you know, using a system like Knock and getting these kinds of improvements over time is just so appealing to me. I really appreciate you taking the time to share about, Knock about the architecture, kind of about your design.

The last thing, just before we go is I wanted to ask you, about any kinds of tools or products that you really love recently that you think the audience might enjoy be it Yes-code style or otherwise. And you did mention a tool that I haven't heard of called Linear. Um, and so I definitely wanna hear about what that is and why you love it so much. And then I want to hear about any other recommendations you have.

[00:58:49] Sam Seely (Knock):

I love Linear. It's an amazing product. Linear is a team of great product builders and designers who I they were at Airbnb before. I might be wrong about that. But, um, they're basically the team that got fed up with using JIRA or like other, you know, issue management systems and decided to build one that is somewhat opinionated and just like really focuses on like incredible performance and speed and tries to get you through like ticket creation and management and all that super quickly. So we use it every day at Knock. Even if you're not part of a team that's ready to use Linear yet, I would just recommend like signing up on your personal email and just checking it out. It's just a really, thoughtfully designed kind of magical product with a few like great Easter eggs and every little detail is just so well thought through and really well executed.

I think like within the Yes-code space we're big fans of well, they overlap a little bit, but both WorkOS and Stytch. So I think workOS does SSO and magic link and I know stitch does some of that. They also do a lot of cool stuff that is not very fun to build yourself in the realm of like SKIM provisioning.

And if you've worked at bringing a software product in the enterprise, that is a, like, very, very deep hole to go down and learn about. They're like blog and their API docs is like just a really great resource to learn about that space and then learn that you shouldn't build it yourself. Stytch does a lot of really cool, like low level primitives around auth. They're also trying to kill the password, which, I'm a big fan of that mission. So those are two, that I really have enjoyed following and are like good tools to check out if you're trying to not build that, you know, part of the stack for your own app.

[01:00:54] John Britton:

I'm always trying to not build things and get things done. I'm a lazy developer. I just want everything to just work out of the box. So I'll definitely be checking all of those out, especially Linear. I hadn't heard of it, previously.

So again, thank you so much for coming on, on the show. This has been a great conversation. Where should folks go to check out Knock and learn more.

[01:01:13] Sam Seely (Knock):

Yes, , knock.app, A-P-P knock.app is where you should go to check it out. Best place to learn about how Knock works is our documentation, which you can just find on the site. It lives at docs.knock.app. That's where to go check us out and we love feedback. We love like finding out where there are limits in our product.

And so if you're reading through that documentation, and have like a cool idea for a use case or something you think we should support that we've don't. Please hit us up, we have a Slack community. You can join in our signup flow, or I'm just [email protected] if you want to shoot me a note, always happy to chat through it.

Thanks for, thanks for taking a look. If you're thinking about notifications.

[01:01:56] John Britton:

I saw on the site on the pricing page. First 10,000 notifications are free, so you can get in and just start trying it out. There's no kind of really barrier to entry. So definitely check it out if you're looking at building notifications in your product.

Thanks so much. This has been a great show.

[01:02:10] Sam Seely (Knock):

Yeah, thanks for having me. It was super fun to, uh, talk about developer tools and notifications.

[01:02:15] John Britton:

To find out more and stay in the loop with Yes-code, head to yescode.org.

© Copyright 2023 – yescode.org.