 Looks like we are ready. So technical difficulties, especially because I'm running flux on my Mac, which looks like the projector system doesn't like. So my name is Pramod Satalge, and I work for ThoughtWorks. I think you may have seen our booth outside. But I work for ThoughtWorks Chicago. I'm not from Singapore. And I'm going to be talking about NoSQL databases. It's not a free lunch. It's just an eye catcher for you guys. But there is free lunch outside once I'm done here. So let's talk about NoSQL. This is more about my experience of dealing with NoSQL databases for the last seven, eight, maybe nine years. And we'll go through the journey of why use relational databases right now? What are the shortcomings of relational databases? And what gave birth to this NoSQL database? I think Mary's talk in the morning will kind of link directly. I was so happy when she talked about NoSQL databases and scale out and that kind of stuff. Like, wow, she's talking just for me. So we'll experience a bunch of that. And at the end, I'll also try to explain how you can pick these databases and what works in your particular use scenario and that kind of stuff. So let's go back here. Like, why relational databases? We love asset transactions. And it's very funny when I go to clients and trying to do NoSQL databases. They say, oh, I want asset transactions in your NoSQL database also. Like, really? But we pick relational databases for these four properties. And as developers, we are so used to this concept. Like, when I write something and I commit, it's there in the database. And we are used to that concept. So something that comes around and that doesn't have this, we always have questions about, is it a good thing to use? The most other thing is the standard SQL interface that we are so used to. You could pick any database. It generally has a select and a star and a from and a table. And you can fire that off and plug it into an Excel spreadsheet or some query tool. And you see data. You're unhappy, like, OK, I can work with this data now. Here, you can interact with many different languages, like you pick Ruby, Python, or whatever under the sun. It generally understands how to interact with the SQL database. If it doesn't, there's always this ODBC or JDBC that you can plug into it and then get to that data if you need to. There's also this whole notion of everyone knows SQL. Like, forget about developers. The QA people, the PM people, you and your business understand how to use SQL. They have used certain tools. They have used certain query tools and stuff like that. And they kind of are familiar. Worst case, they'll at least know how to do a select star from a table. So here's my daughter trying to do some select star when she was, like, six months old. So this knowledge is very prevalent. So replacing a relational database with something that doesn't support this kind of querying paradigm is sometimes mind-boggling to a lot of people. This doesn't support select star. What do you mean? So that's why it's adoption-wise. It becomes difficult for people to understand that some of this doesn't actually sum up. The other thing is limitless indexing. If you come up with a table schema and after some time you figure out, I need to query this table in a different way, and someone has this brilliant idea. Let's just add index, and it magically works. So that notion of limitless indexing is one of the reasons why we use relational databases. Because you could come up with a schema right now. And later, when you have a different need on that schema, you can add indexes and make it work. There's also many different data models. Like, if you say I want to have a key value, like a key and a blob, you can do that in relational databases. If you want to have a document store, a key, and some kind of document, you can do that in relational databases. If you want to graph database, you can do references and that kind of stuff. You could do that too. So there are many different data models that relational database supports. So we are comfortable with that idea. So of course, given so awesome things about relational databases, why even come up with the idea of NoSQL? What's the need? So here are some reasons why you would do NoSQL databases. First thing is schema changes are hard. Talk to any person and try to change the schema in production databases. It is really hard. You may know how to do it, but there are 10 different apps that are talking to your database. I think Mary mentioned database integration. That's a big anti-pattern here. Once everything is integrated into the database, changing the database becomes super hard. If you change a column, rename a column, drop a column, stuff like that, some obscure app somewhere starts breaking because that column doesn't exist anymore. So schema changes are really hard. The other notion is this impedance mismatch between the way the developers think about objects and the way it is stored. If you look here, here's my nice little customer object has its line items and invoices and payment stuff. When it goes into tables, you have a table of orders, a table of customers, order lines, credit lines, and that kind of stuff. And there's this big impedance mismatch between the way a developer thinks about an object and how they interact with each other and the way it is stored in the database. And where to reconstruct, you have to come up with this ORM mapping layer and that kind of stuff. I think it was early 2003 or 2004, someone mentioned ORM being as the Vietnam of computer science. And I still think it stands true. This whole other notion of application versus database integration, this is what we are used to. Everything is dumped into a database and applications kind of read from it. And if you need to pass something to the other application, you write a thing in the database and the other application picks it up from there. So this is a big integration database. And changing anything here is super hard. We have moved to this way of working now, like long time back. I think Mary was mentioning the same exact thing in the keynote in the morning, where integration happens at a service layer instead of at a data layer. So if your app needs something, it basically asks the other app, give me this stuff. Now what that does is freeze you up to decide what is good for my app. So my app may be better off using a graph database versus your app may be better off using a relational database. If you are integrating here, you're forcing this person to use a relational database, not the database that suits their purpose or suits their need. So that's one other big need. The other is this scale out problem. Like running relational databases in a cluster mode is super hard. You take whatever database like Postgres, MySQL, and stuff. Most of them are write ones, read many times kind of stuff. You can go with the Oracle Rack, but of course you are going to basically be going to a bank and getting a loan to buy Oracle Rack. So that kind of stuff is, again, discouraging people to use this kind of notion of running stuff on a big cluster. So that's why no SQL databases are, again, picking up. There's this notion of unstructured data. I'm going to get data from multiple places. Like IoT is picking up. You get a bunch of stream from everywhere. Where do I stuff this? By the time you actually come up with a model to store that data, the type of stream data that's coming in has already changed. So you don't have the time to model the data that's coming in anymore. So you just want to store whatever is coming in at whatever shape and form that's coming in and at whatever rate it's coming in. The other notion is this whole uneven rate of growth. So some startup comes in and says, awesome. We are going to be so nice. And we are going to be so awesome. We're going to get a million users in a month. So let's buy a big machine for it and that kind of stuff. And a month later, there are two users on the system. That whole notion of design upfront has fallen apart. You could be the other way around. Let's figure out what happens. And a month later, there are three million users and your machine's already short. So that's where this horizontal scaling helps. As users get added, you just keep adding more nodes to your cluster. Don't worry about buying a bigger machine or a smaller machine and that kind of stuff. So it's this uneven rate of growth that's really also driving this. One other big notion of design specifications that we're actually doing is this domain-driven design concept of basically trying to deal with data. So if this is your domain, you are basically converting that when you stored into the database in this impedance mismatch way of this basically converts into this. What if you could take that object and then persist it as is? Like the whole model, the whole domain model can be wrapped around into a single object and then you can push this around. So here, for example, that would be your key and this whole thing is your value as an object. And you can move that around. You're basically embedding the objects themselves. This could be a JSON showing like this. This is my customer ID and here's like Martin as a customer and has a bunch of things on it. That whole thing is your object. When you get that customer, everything about the customer comes with that object. So you don't need to go back to the database to do multiple trips. So that helps in that particular way. So you're representing this aggregate as data. You could also do a split aggregate. Like sometimes say, oh, if a customer has a thousand orders, am I getting all those thousand orders back? Does it increase network traffic and that kind of stuff? You can also definitely split it around. Like this being my customer object and this being the individual orders. And then I'm referencing the orders as array of order IDs here. So that's one more way to do it. You can also represent it at here. Like this is my customer and these are a bunch of orders that I have. So what happens once you go to this aggregate orientation way of doing things is it frees you up with a bunch of constraints that are on it. So one good constraint that frees you as relational databases don't have this concept of aggregates. You could do a materialized view or you could do stuff like that. They are still roast. You are not aggregating complex objects as such. It is also giving you, like once you have an aggregate, it reduces the need for acid compliance on that particular scenario. So let me talk a little bit in detail about this. When you have a customer object that has a bunch of invoice items on it, when you write to a relational database, you want to make sure they write on that each one of those tables is successful. And when all of that is successful, that's when your transaction becomes successful. And the need for acid comes in because you don't want two table writes to go successful and the third fails because the object is in an invalid state at that point. But if you have an aggregate, if the aggregate write is successful, you're good. If it fails, you can retry. So that's why once you go to the no SQL way of doing things, you're dealing with an aggregate, not with individual bits that get returned to different tables. That's why the need for acid is reduced significantly when you go to no SQL databases. It also is better for clusters. So imagine if you have a Oracle cluster and the table has to reference other tables in other machines that have their own storage and that kind of stuff, doing relational stuff in databases becomes really hard. So that's why doing clusters in relational databases is hard. But once you have aggregates, you can take the aggregate and store it on a machine and you don't have to worry about the dependence of that aggregate because everything is along with the aggregate. So you can push that aggregate in different places and then not worry about the dependence of the aggregate. That's why a lot of this no SQL databases are very good to form clusters around because you can push data around very easily. Most of these no SQL databases can be segregated into these three major categories. I call them key value document and column family and we'll talk about each one of them about their properties and what they're good for and stuff like that. So let's take key value databases. If you are a programmer, a hash is a key value database, basically like hash, it has a key and a value. There's one key, there's one value and the value, you don't really care what's in it. Like your database doesn't know what's inside that value. It's basically like a hash and some of these could be distributed. For example, memcast is just on one machine, there's a key and a value, but react, there's a key and a value and you can distribute it on a multiple machine. So we'll talk about those two. So here's an example of comparing them. So if you are familiar with Oracle, there's an instance in react which is a key value store, there's a cluster, a table is a bucket in key value store, a row is a key value and a row ID is basically a key. So what happens in this kind of databases, you have a key that you put into the database with a value attached to it and when you retrieve, you should know the key before you retrieve it. You can't just ask the database, like give me all the keys and I'll kind of iterate over them and figure out. That will be a super expensive operation. So when you are going to do like a key value store, you should know the key before you get to the database. A very good use case for this would be like session ID. If you're storing session information, you already know the session ID, you put in the database with the session ID, whatever stuff you want to store for the session, you get back to the session ID because you already know the session. Another example would be like user preferences. For a user ID, these are the preferences. So you stuff in the user ID as a key and all the preferences go in as the value for that. So let's take an example. So imagine you are storing properties of a car in the database. So the key, which is a vehicle identification number, is unique globally. You pick any car. It has a global identification number on the car printed. That's your key and the value is basically a bunch of stuff inside there. So here's an example of a JTDR. This is my car, a Toyota car. It has that unique number and then I can do a bunch of stuff here. So I am saying Ford here just to confuse you, but the idea is there is a value here and you can put a bunch of things inside it. So imagine you are storing history of repairs done to the car. So you can say, that's my key, that's my value. Whenever a new repair is done, I can put more stuff in this value bucket and keep storing information. When I'm retrieving, I've given a win ID because a customer comes in with a car in your shop and you know the win on the car. You look at that win and pick up this and you basically get the whole history of the car in one get. So there's a get and a put and that's about it. There's no relational stuff, trying to query a bunch of tables and stuff like that. So it's very good for that kind of scenario. So here are some examples of key value stores. RIAC, as I mentioned, is a persistent key value store. Redis is not, Project Aldermatt is a persistent, Memcast is not, Couchbase is and there's Oracle NoSQL. If you create a software, sure, go for this. The idea here I'm trying to say again is even within the key value store, there are different options and variations that you have to pick. So the way I think about this is, relational databases gave you certain properties that you could depend on. So that's like an automatic shift car. If there's certain options you are given and that's how this works. But once you go to NoSQL database area, you have to pick and choose what works for your used case. You can't just say I'm gonna use a key value store and I need to persist the data and I'm gonna use Memcast. That's not gonna work, because once the Memcast machine goes down, your data is gone forever. So you have to pick what works for your used case in the right way and that's where the choice comes back to the designer, the developer, the architect, instead of the choice being decided by the product itself. So that option is given to you which is liberating in some ways because you can choose what works right for you and sometimes it's confusing also what do I pick. So you have to be a little bit more read up on all the properties of these kinds of databases and also understand what your used case that is you are solving for. So you could use this for session storage. You could use this for user profiles preferences. You could use this for like shopping cart, especially like Amazon. You start shopping and you basically close the window, go back, come back a day later. You'll still see your shopping cart. So they are using a persistent store for that which is distributed. So if a person puts something in the shopping cart, a machine in the cluster goes down or stuff like that, you still want the shopping cart to be there. So that kind of stuff, they basically use something like React which is a persistent store, persistent key value store. You could use this for single user analytics like for example, a user visits my website, what time you visited, what time she did this, that kind of stuff. You could store like a log of, timestamp log of visitors for a key like user ID and basically a bunch of log going against that user. So all of these use cases are good scenarios to use like a key value store. So the next is a document database. A document database is just like a key value store, but the value part of the database is visible to the database. So it can interpret it, it can query on it, it can give you subsets of it and that kind of stuff. In a key value store, you are basically getting the whole value back no matter what you want out of it. You may just need a single piece out of it, but you're getting the whole thing back. But in a document database, you have the choice of like, give me only this part of the document kind of stuff. So again, there's one key, there's one value and the value is visible to the database and the value can be queried upon. And you can store JSON or XML documents in this. So again, comparing back to a known thing which is Oracle here to MongoDB, your instance is basically MongoD, your schema is a database, your table is a collection, your row is a document, and your row ID is this underscore ID that the database keeps. So just so that you can compare. So here's going back to the same example. If you have an ID of a win, your document is a car fact. Now you can see this is a nice little user readable document that you can get at. So a good advantage of using this over like a key value store that is basically a blob is when you get the blob from the database, your application needs to interpret it. Other humans cannot necessarily see it. Here you can query the database directly from a command line query or some user interface-able stuff and you can still see what the data is which is more describable to you, right? So here are some examples of document database like MongoDB, RavenDB, CouchDB, Elasticsearch if you don't know easy document database, OrientDB and RethinkDB, right? So there are a bunch of these databases, all of them are open source, you can download and play with them and decide for yourself how they work. So here are some use cases for them. Event logging is one, like bunch of events that are happening, you can use them for event logging, you can use them for like prototype development. I was talking to someone yesterday in our office about this notion of like coming up with a model to work with, right? When you are doing some new development, coming up with a domain model itself takes more time and on top of that, if you want to translate that domain model into a relational table, you're spending more time. So why not take that object as is and start storing it in the document object and once you have a good document, once you have a good domain model of the object, at that time you can decide what kind of persistence do I need? Do I need relational, do I need document and that kind of stuff, right? That makes more sense because the domain discovery itself takes a lot more time. You can also use this for e-commerce apps like bunch of like websites that should display like catalog information and stuff like that is very useful. Content management applications are really good fit for documents because nowadays you take JSON from the database and your JavaScript app in the front can understand JSON natively, so you just use to paint that screen. There's nothing translating that stuff in the middle at all, right? So all the like document to like relational translations, fojos, transformation objects just go away, makes your architecture a lot easier and simpler to understand. The next database type is this column family database. So if you want to think of this, it's a hash that's embedded inside a hash that's a simple way to think about it, right? So within the hash they are as columns and each row has a row key and then columns have version data. So whenever you write something on top of the column, most of these don't necessarily discard the old data. The old data is still around so you can query versions of your data like customer name, change from like promotes to like promote Kumar, then now change back to promote and if you wanted to keep audit of that, that's like readily provided by this database, you could just look up the history on that, right? And you're like comparing it back to like Oracle here, instance is a cluster, a database is a key space, a table is a column family, a row is a row and then you have columns here too, you have columns here too. The only difference is in the relational database, every row has the same number of columns, no matter what you do, right? In column databases, you could have varying column, like one row may have three columns and the next row may have 20 columns, all of different types, so it doesn't matter, right? So that's a big difference in the way you think about column family databases. So here's an example again, going back to our car properties. So my ID is still the ID here, this is the key for the row and the row itself has a bunch of hashes here, can be a make of four, the year and all that stuff can sit here, then the model can sit here, the service again can have a key value and it can embed a hash inside that too, right? So it can be a hash of hashes, they are called column families. So what this does is I can get this key and say, okay, I just need the service history, I don't care about the rest, you can say this key and I need this service and it just gets you the history inside it without getting you the rest of it, right? So that's where access becomes much easier, even writes become much faster. So that's why you see column families databases being used, especially where you have a super high write volume. Like imagine you have IoT kind of app which is sending a bunch of streams and like literally lighting millions of writes a minute kind of scenarios, right? So you can deploy these kinds of databases to do that. You can also use this for like content management, there's a bunch of content that you want to show. You can also use this for like e-commerce apps when you have like basically backend processing or fulfillment centers which need to be very resilient for any kind of downtime and things like that. So there's this whole other section of databases called graph databases, and I don't necessarily call them as no SQL databases. For the simple reason, they have a totally different paradigm of thinking about things. So let's say graph databases, we are used to this notion of relations between objects and things like that. In relational databases, the objects don't actually relate to each other. You infer that relation based on your own knowledge of the database, and the database only enforces that the data exists. It doesn't actually know the relationship, right? So for example, when I have an address here and a customer and I have this build to relation, in relational databases, you're just saying this ID should exist here, that's about it. It doesn't know that this is a customer, this is address and this is a relation they have. In graph databases, you can make that relation much more explicit and you can traverse based on that relation. So for example, if you pick one address from a graph database here and say, give me all the customers that are pointing to me, right? Then you can get a list of all the customers that are using me as a build to address, right? So that kind of relationship traveling is very powerful, especially in a network based kind of solution that you need. This is a e-commerce model here. I have a product that some customer purchases. The customer uses order payment, that's where this order payment belongs to. This order was paid with this order payment, for example, and this order includes this product or is part of this product. So you can model your domain much more easier in a graph database and you can query them in an infinite different way, right? So it's a multi-relational graph that's very important to understand. You can have incoming relations and outgoing relations and things like that. And the relations themselves are first class citizens. The most important part of a graph database is there are a bunch of algorithms already implemented in the graph database, like shortest distance or longest distance, all possible routes, bunch of those algorithms are pre-implemented. So you don't have to do that yourself when you start using non-graph databases. So here we'll see why using them is more useful. Like for example, connected data. You may have connected data, like this customer bought these things, these other customers bought these things and you want to do a recommendation engine kind of stuff. You can use graph databases for that. Like generally when customers buy this, other customers also bought that kind of stuff, right? So that's for that connected data. I think Singapore is a big banking hub. You could use this for routing things too, right? Especially if you use this as a customer where they wanted to route money from one bank to another bank going through whatever routes, the Swift course allows certain routes and then you can calculate for cost, like what is the cheapest way to get money there or what is the fastest way to get money there or what is the least amount of steps to get there, that kind of stuff. So you can calculate them based on different cost criteria that you have. You can also use this for location services, like for example, I am right here, what is closer to me. For example, like say, beer, for example, what is the closest place to get beer at this location and then you can do geolocation kind of searches around that too. Recommendation, like I said, is a good use case for that particular scenario also. So all of this notion then become, like people say schema less, like no SQL is schema less, like really? No, it's not schema less, schema is in your code instead of in your database, right? So you need to understand that first. Like a lot of people just go into no SQL, schema less, oh fine, okay, I don't need to worry about schema. Now you have to worry about schema because schema is in code, like when you change the name of the attribute, like in JSON, you change the name of the attribute in the code, the old data that's in the database, you cannot access that anymore, right? You cannot pass that anymore. So you need to write data migration or you need to write your code in a different way. The only advantage here is in relational databases, when you do schema migration, you basically migrate it for everyone by default. There is no option of this user or this particular object gets it and this user or this object doesn't get it. There's no option like that. Everybody gets that new schema by default. In no SQL databases, we have that option and you can change the schema whatever way you want, but if the application can understand the old schema and the new schema at the same time, it's all fine, right? So that's what I call as a lazy migration. So when you read, you read the old schema, when you write back, you write back the new schema and that one object got migrated at that one time, the other objects could be still in the old state or the new state, it doesn't really matter. So this kind of deployment technique and my data migration technique is really useful for keeping apps 24-7 up, right? Because you don't have to bring the database down. Even if you can do a schema migration without bringing the database down, the table gets locked so the app gets affected, all kinds of stuff just goes away because you can migrate one document or one object at a time, right? So it's a very powerful way of keeping systems up. So this brings to the notion of this polyglot persistence, right? Like this graph database is good for this, key value stores are good for that, how do I incorporate all of this in my organization, right? So you can use different storage techniques for different kinds of use cases. Like for session storage, I may use key value for like recommendation is engine, I may use graph databases and different things for different purposes, right? And this can be a cross at the enterprise or within the same application too, right? Your application itself needs different use cases or within your enterprise, there may be a platform as a service and one service they provide is a graph storage where you send nodes and get nodes and ask queries. The other may be like a column family store where you push something, get something kind of stuff. It may be a platform level or within the same application, right? And the biggest thing is basically encapsulate all of this with services. Like don't just talk directly to the database but talk via services so that you can later change them if you want it to. Like let's say you may go to a key value store and later on decide, oh, maybe a document would have been better. If it's wrapped behind a service, then you can strap it underneath it without having to worry about how others would use it, right? So here's an example of how you would use this. Like for example, the e-commerce platform, some new stuff, some old stuff and some new stuff being introduced. It could also be a very simple stuff. Like all of this could be here and just to make search easier, you can put a search engine in here and that's also polyglot persistence for you, right? There's a lot of these things that can be implemented. So obviously you're writing the title, free lunch. Like what do I mean free lunch? There is free lunch after this. So hang on. So given so much of choice, how do you pick what's the right thing for you, right? So if you look today like on noSQLdatabases.org, there may be easily like 60 databases to pick from, right? So which one do you pick, right? So one way to look at this is for choose for programmer productivity. Your startup productivity is important. Like let me pick for that. The rest can fall later when we scale up and that kind of stuff. The other way be you can choose for data access performance. Like I need to write a million writes a second. Like what database gives me that property? You can pick for that. Or you can say I'll just stick with the default because I know this stuff, right? So then you're paying the cost of scale up, scale down, vertical scaling and all that kind of stuff, right? The best thing about this is most of them are open source, right? So basically you can download and play with them and test based on your expectation. Like this is what I'm expecting from the database and I think this will work for me. So install that database, play with it, understand how it works and see if it fulfills your needs, right? You don't have to pay anyone for anything, right? Most of these are basically you download and they're all open source, right? Most of them at least, right? They're all open source. You can play with them. So that's all I had to say. I'm here till the end of the day. You can ask questions now or find me later in the halls somewhere. Oh, thank you. Sorry, I have a question. Okay. So oftentimes we have so-called reference data that is needed by other entities. For example, in the finance industry, security reference or other similar data. So if we would like to put such data into no-SQL database, first of all, oh, well, okay, the first question is really should we just put such data into some sort of no-SQL database or even relational database and let the programs, the applications that need to access such data, directly connect to this no-SQL database to tap on its scalability and the performance, or we should wrap such data using microservices and then expose such data through microservice because one concern with microservice would be whether they can be fast enough if they go through HTTP and JSON. Right, so you can do two different ways. One is if more than one app is gonna use that reference data, it's better to wrap it in a microservice and create that nice abstraction of the access layer. If your app is the only owner of that data, then you can make the app talk directly to the database and then you can gain that the app knows its data and then it knows how to deal with it and then you can make sure that the app understands the data in there. So once you go down that route, you then cannot open up the database for others to write into or do like schema changes and stuff like that, because now your app will not understand that data. So there are two routes to pick based on how far you want to extend and expose this data. Okay, but if you want to do a microservice for this data, does it mean that all the other applications need to query this microservice every time they need that data? Right, so if you imagine you want flexibility in the future and you want to not make the other apps dependent on the schema in the database, but dependent on the nice interface your app exposes, so that flexibility is needed, then it's better to talk to the app via microservice or via REST call or whatever that is instead of talking directly to the database. Once they hook into your database and you change the schema, they get broken because they are now referencing a schema that doesn't exist anymore. So if you don't want that fragility, I think one of the things that Mary mentioned is make it antifragile. So that's the way to make it antifragile is when you change the database, you don't want anybody else get affected. And the way to do that is make them come to you via a service, a nice API that is exposed, and then you can have like contact-based testing and all kinds of stuff wrapping that API properly. So if you change something, those tests will break, then either you fix the API or tell them to like, okay, there's a new API, like migrate to this new way of doing things, right? Yeah? NoSQL databases, is consistency and arithmetic possible if we are working with a cluster across the geographical nodes? So consistency and availability is a question here, like with no SQL databases. So no SQL databases were actually born based on the CAP theorem. So how many of you know CAP theorem? I didn't specifically go into that. So CAP theorem is consistency, availability and partition tolerance. And the theorem says you can have only two of them at any given point. You cannot have all three. There is no way you can do that, right? So if your app needs consistency, right? So then you will have to like give up some of that partition tolerance or give up some of the availability, right? So relational databases are geared a lot towards consistency. So you have to give up availability and partition tolerance because once the machine goes down, the database is not there. So you have lost availability, right? Or in a basically a network kind of mode if the network goes down, you have basically lost that connection so your database is unavailable. So that's why relational databases are more towards consistency heavy. Now you can pick other databases, like for example, if you take Mongo, a three node cluster for example, and you want to gear it more towards high consistency, you can for every write, when you do a write, you can say this write needs to reach all the three nodes and then tell me that the write is successful. So you have basically made the Mongo cluster highly consistent, but now you have made it less available and less partition tolerant because one node goes down, the write will no longer be successful, right? So you have to decide what your app needs. That's the biggest thing here and that's what I was saying in the beginning is as a developer, you have that choice in your hand now. In relational databases, that choice was made for you. We are going to go for consistency, you have no option. But in NoSQL, based on the same parameters, you can say, okay, I want to go for high consistency and I want to, I don't care that much about availability. Now you can make this choice even on specific writes. So for example, customer name changes, I want this more consistent. So you can say for the customer name change, when I make that write, I want this to be more consistent. So I can say for this write, make sure it reaches at least two nodes before you tell me that it's successful. So it's more consistent. And other stuff like event logs and stuff, you don't care about it, you say, just accept and just tell me I'm done, right? So you can, based on that use case of each write, you can decide what kind of consistency you want, right? So as a developer, you get more choice, but with that choice comes more responsibility, right? So you have to make that the right trade off, yeah? And each one of those databases that listed gives you that choice. Even in key value, even in document, even in like column family and even Neo4j, for example, the graph database, gives you that choice, yeah? All right, there's free lunch outside. Thank you for sitting. And while you go out, please comment on my talk here, green or red, simple UX.