The Carnegie Mellon Vaccination Database Talks are made possible by Autotune. Learn how to automatically optimize your MySeq call and post-grace configurations at autotune.com. And by the Steven Moy Foundation for Keeping It Real, find out how best to keep it real at stevenmoyfoundation.org. We're studying today to have Steven Walkanus, the Director of Engineering at Vertica. He's been there for a long time, certainly in the early days before they were acquired by HPE, and then obviously when they were moved on to bite the promise. So as always, if you have any questions for Steven, please unmute yourself, say who you are, and ask your question directly, Adam. And feel free to do this anytime and interrupt him, because that way you want him to feel like he's actually giving a talk in front of people and not to his laptop and zoom for an hour. So, Steven, with that, thank you for being here. The floor is yours. All right. Thank you very much, Andy. And yes, please do interrupt and ask questions. I want to deliver the information as clearly as possible, and it'll help to clarify for yourself and for others if you interrupt me and ask me questions. I titled this talk High Performance Over Varying Terrain. You could look at the varying terrain in two different ways. One is that Vertica has customers who are deploying our system on very different scales. We have some that are running single node Vertica instances on a couple terabytes of data. We have customers like the trade desk who are running in the cloud, and they have replicated databases, one on the east coast, one on the west coast. Each of those databases is over 600 nodes and 12 petabytes of data. So even within a single version release of Vertica, there's quite a variance in the way that the product is deployed. The other way you could look at the varying terrain is that Vertica was the inception of Vertica. The pre-store paper was published in 2005, and obviously over the time, since then to now, there have been substantial changes in hardware in the way that the database is deployed. I chose these images carefully. The one on the left, the Jaguar, is their Formula E race car. Jaguar is a partner of Vertica. They're using our database to do analytics on data that they're collecting, metrics that they're collecting during the race.  And then they're using that both to provide optimizations during the race and also to do comparisons after the race and figure out how they can race better. If you didn't see the Vertica logo on the first time, I added this obnoxious red arrow to make it clear. So that's on the actual Formula E race car now, the Vertica logo in the partnership.  It's a partnership. So they're using our products in doing analytics on racing data, and they wanted to recognize us as part of that partnership. So they actually approached us about putting the logo on their Formula E car. And of course, we thought it was awesome to have it appear there. So a little bit about what is Vertica. I'm sure many of you have already heard CSTOR or Vertica distributed SQL analytics database. What's it mean to be an analytics database? So we're answering questions that require doing computation over oftentimes billions of rows. So a simple example might be, show me the stock ticker symbols that are most frequently traded over the past month. This Vertica was commercialized from the CSTOR paper that was written by like Stormbreaker and many others. At the time that I was interviewing at Vertica, Mike had already moved on, become bored with OLAP and he moved on to OLTP. And it was actually the OLTP group, the VoltDB folks, which if you're not aware, Volt stands for Vertica Online Transaction Processing Database. It was actually those folks that I first interviewed with and I missed an opportunity to work with Andrew Pavlo. One of my great career regrets, fortunately, I joined an outstanding team at Vertica and it's been an awesome experience for the past 13 years. I started as an individual contributor and I've worked up through being a manager, opening an office in Pittsburgh and director of engineering at Vertica. All of you know that enormous amounts of data are produced every minute. This is from 2019. One thing that I found interesting here is that the number of emails sent is 10 times the number of text messages that have been sent or received. Another thing that's interesting to think about is that though the way this data is collected may have changed dramatically over the years, you think about emails and text messages and so forth, they don't need to be stored in transaction processing systems because they're not updated. Something like a log structure and merge tree will do just fine as long as it has some reliability guarantees applied to it. Though there was movement away from consistent analytic systems to eventual consistency, there's been a large migration back to systems that have guarantees around consistency because they're much easier to reason about. And as long as they can scale to handle the magnitude of the problem, then it's better to have consistent results than have to worry about ones that will eventually be consistent. Vertica is heavily used in a number of different verticals, FinTech, AdTech, and so forth. One of my favorite examples is in the healthcare space, CERNR has developed a system that they call health facts that they use to detect early onset of sepsis. Sepsis is a bacterial infection that when detected early, it is relatively easy to treat with antibiotics. However, when it progresses to some to later stages, it becomes very difficult and expensive to treat with long hospital stays and a 50% mortality rate. And so it's been really neat to see and work with the crew at CERNR and the advancements that they made on early detection of sepsis and the millions of lives that they've been able to save because of that. In general, Vertica's customers value performance and flexibility has been performance since day one when Vertica was outperforming row stores by several orders of magnitude. In today's marketplace where you have options to deploy on the cloud, on premise and private cloud and Kubernetes and so forth, Vertica supports all those options as a software only product now also with our Vertica accelerator, which is our as a service offering for Vertica. And so we have a breadth of flexibility for our customers to be able to deploy the product and we have some customers who are deploying both on premise, replicating into the cloud where they can handle bursty workloads, especially for those who are in e-commerce and see a big rush during the holiday. All right, so that's more of what Vertica is and where it's positioned in the marketplace. If you've read the Seastore paper, then these five pillars are going to be very familiar to you. Vertica stores its data in projections and one of the important attributes of projections is that you can specify the sort order. So if you're storing stock trades, for example, you can specify that you're going to order the entries first by symbol and then perhaps by date or other attributes of the table. One misconception that I find people have about projections is that they think each of the columns is sorted independently. When we're sorting rows of data, say you're doing an insert into a Vertica database, then the sort key specifies the order in which we're going to sort those rows. Each column of the row is going to appear in the same ordinal position as the other columns. So we're sorting by a key, but it's an entire row that's positioned in the projection. Projections are sometimes confused with indices. They do some things that are very similar. Improving the performance, the optimizer can use the sort order of a projection to say, you know, efficiently apply a predicate. A significant difference between projections and indices is that projections are stored in sort of a log-structured merge tree. And so they can be created at the same time that data is being queried. There's no need to turn off the indexing that happens with projections, as there was with databases that support indexes. The other significant difference is that when you've done the binary search to find the range of values that match your predicate, within an index you would then have positions that you would go and you would look up to find the actual values corresponding to that range that you had found in the index. And those positions require seeks on disk, which can be quite expensive, whereas with projections you have the entire table sorted by the same order. And so when you go and look for the range of values that match that predicate, you're then doing scans over all the other compressions. All the other columns, I'm sorry. When storing data oriented in columns, the entropy going down the column tends to be much less than the entropy going across a row. And so we get compression levels that on average are 10x above the raw data size, oftentimes significantly greater than that, especially for those columns that appear in the sort order. We can also do RLE encoding of the data. So if you have stock symbols and you're ordering by those symbols, there are only a few thousand symbols. There are billions of trades. So we get a sort column that has only a few thousand entries, and then the run length encoding tells you how many recurrences of those entries appear in that run. The data is columnar, which has been a significant advantage from the beginning, but now these days it's more so than even in the early days of Vertica. With columns, you can do joins before loading the data into the database and avoid doing those more costly joins at query time. So we see a lot of customers who are denormalizing their data gaming companies, for example, when they have a new game, they'll add a new column to the database for the games that don't use that attribute. They're storing null values. Those null values compress very well. There's very little cost to adding columns that are infrequently used or that are sparse to a column or database. The evidence that we've seen in our product is that we went from supporting 1,600 columns as the maximum limit, to now supporting 10,000 columns in the database based on the request that we've had from customers. Another attribute of a projection is that you can specify. By 10,000, it feels like an odd number. Why not add the 16 or whatever it might be? Well, yes. You often find in the code-based places where we've rounded down based on it being... It's easier numbered to provide to customers than a 2,000-something value. But you can tell them it was 10,000 versus 2,000 or whatever. Yes, and it's actually a knob that controls this. We set the upper bound at a particular limit. It really is workload dependent, but that was a safe limit that we felt comfortable with. It will depend on the types of columns themselves. If you have very wide VAR binary or VARCAR, then you're going to get fewer than those, at least for a performance that's acceptable. I'm thinking Oracle Famosity has 1,000 because it's hardcoded in the code. It's hardcoded in the source code. All of the players, they told me they already changed it once and it's such a big pain. To change it again would be a major undertaking. Nobody wants to do it. When we bumped the limit up, we put it behind a knob so that we wouldn't have that problem going forward. If you know which knob to turn, you can turn it up above 10,000. As I said, depending on the types of the columns, if they're all integers, you can certainly turn it up without running out of resources, especially on these 1TB memory machines that people have these days. You have to pick a number as the default and 10,000 was what was chosen. Another attribute of projections is that you can specify the segmentation. Vertic is very careful about the way we place each of the rows within the cluster of nodes. We do this so that we can apply optimizations like co-segmenting group buys and co-segmented joins. If you've segmented a projection on keys that you're going to use in the group buy, then we can apply that group buy without having to redistribute the data among each of the nodes in the database, similarly with the co-segmented join. I don't know if we'll have time to get to that part of the presentation, but if we do, we'll talk about how elasticity is impacted by that choice of careful placement of the data. Drilling in on projections in a little more detail. Using this trade's example, if we decided to sort by symbol and secondarily by date, the trades table might have many other columns like the bid and the ask price, the quantity that was traded, the broker that made the trade. It's common that if you're storing data in an analytic database, you want to store everything. Just in case you later find out that some bit of information is useful. As I said, each column of a particular row is stored in the same position. That means that when we search the symbol column, we can do a binary search on that since it's first in the sort order, that then any of the other columns would appear within the range that we find, in this case for the apple ticker symbol. For the query that I've included in the bottom left there, where we're selecting the minimum date of any trades made on this apple symbol, because the date is second in the sort order. This is a matter of simply finding the first block within the positional index, which I'll talk about in just a second, and we don't need to scan beyond that because we know that the dates are sorted and that the first one is going to contain the minimum, once we've put a constant value on the symbol. Drilling into the structure of the content as it's stored in the database, each column, at least logically, is stored in two separate files. There is what we call a positional index or the PIDX file. That contains the min and the max value as well as an all count and a CRC so that we can check for file corruption in the FDB file. An offset into the FDB file, the uncompressed size of the block that's stored within there, and the compressed size as well. The FDB file is the file that contains the actual data. It's been encoded and compressed, though I've shown it here in plain text. Obviously, it's as stored on disk. It would not be human readable, though if you could guess the encoding or if you had the catalog and could look it up, then you could unencoded, uncompress it, and read the data. So it's not encrypted, at least not without additional functionality being applied to it. For integers, we take a block of 64k, a buffer of that size that's already been encoded. We run compression, might be LZO, or a delta compression on it, and then we store that data compressed in the block. So what's happening when we're doing a search for a range of values within the PIDX file, we can do a binary search because we've ordered by that column. When we find the range of values, then that's pointers into the FDB file where we can find the compressed blocks, and then we can uncompress and jump to the ordinal position within that block to find the corresponding column, entry or cell entry. There's a trade-off, obviously, between the size of the block that we're compressing. Bigger, we would get better compression, but too big, and we end up reading a lot of values, uncompressing a lot of values that aren't going to contribute to the calculation that we're making in the query. So there's a trade-off between too big and wasteful uncompression and too small and don't get good compression on the data. So looking at a relatively simple plan to load data into a Vertica database, if you've read the CSTOR paper, it makes mention of something called a buddy projection. This is a replica of the projection that can be used for what's called in the CSTOR paper case-safety. So for case-safety of one, you need at least one replica. That way you can lose at any node in the database and continue running. And in fact, as long as you lose more nodes than just that one, as long as you don't lose any two buddy projections. So you still have a consistent collection of the data. In the CSTOR paper, it talks about each of these buddy projections being able to have a different sort order than one another. So the benefit of doing that would be that the optimizer can choose the projection that's best suited for the particular query. So in the previous example where I was using symbol as the predicate, if there were a projection sorted by symbol, the optimizer would choose it. If I then queried and used timestamp as the predicate, then the database would look for a projection that had the primary sort order as the timestamp and use that for the query results. So what's going on here is if you read from the bottom up, the load is the thing that's parsing the tuples, parsing the limited file or parquet or orc and turning them into tuples. They then get copied and sent to this resegment send. The resegment send is then going to look at the segmentation key of each of those tuples and determine which node to send it on to. It gets received by that node. And then the data target, the thing at the top is what's doing the sorting and coding, compressing and writing out those PIDACs and FDB files. So in this plan, the copy is being done to the in-memory representation of the tuples and then those tuples are being sent over the network to the primary and to the buddy node. It wasn't long in Vertica's history until we discovered that having buddy projections with different sort orders is a bad idea. Does anyone want to wager a guess as to why that is? So if you think about... Sorry. It makes recovery harder? It makes recovery really, really difficult. If you have terabytes of data that are stored in, say, your largest fact table on each of the nodes, then those terabytes of data have to be resorted in order for the node to recover. And that's a relatively expensive operation to run. In some instances for our customers, it was taking them many days to recover. And DBAs are usually... Their heart rate is elevated whenever recovery is going on. They're worried about that replica copy going down and losing the database or having to go back up to recover it. So it turned out that having buddy projections with different sort orders for a large-scale database was not a good idea. So we were quick to address that and change the original plan so that... Well, we actually just put the requirement on the projections that you couldn't create a buddy with a different sort order. That was easy to do, relatively easy to do. But then with the previous plan where we're making copies of the tuples and re-segmenting them to each of the nodes, there's an inefficiency because the copy of the tuple is significantly larger than the compressed and encoded ROS format in the PIDX and the FDB files. And so we rewrote some of the code and redesigned the load process so that the records were fed to a single data target for that segment of the data that was being written. And then once the ROS file was created, the PIDX and the FDB files were then streamed, pipelined over to what we call the data target proxy. So that data target proxy was a pretty simple operator that was just receiving the storage format and persisting it to disk on the buddy node. So that's a high-level explanation of what's going on when data is loaded into Vertica database. Digging a little deeper into the data target itself, you can see that there are multiple threads that are working on queues to do the sort in parallel. So you might be loading massive amounts of data into the database. We want to make use of all the processing power that we have in order to do a sort. The sort might have to be done in multiple merge phases. So if we've loaded large enough amounts of data, we load it into a large buffer. We do something like a quick sort in memory. We compress that data. We write it out as a chunk. And then if we've done that with very many chunks of data, we might have to make multiple passes in order to do the merge efficiently. If you tried to do the merge all in one pass, you wouldn't have enough resources to be able to keep the data buffered and you do a bunch of disk seeks every time you're trying to access the next record in the compressed chunk of sorted file. And that would be very expensive, more expensive than doing it in multiple passes. Once we've done those multiple passes over the sorted chunks, then we're writing it into the PIDX and FDB files and then streaming those over to data target proxy as those are being written. Today, when we're writing to our persistent storage, it's shared storage. It's S3 or HDFS or Google Storage and GCP or the Blob Storage in Azure. However, it still makes sense for us to also send another copy of the data to some of the other buddy nodes. In this case, we call them subscribers because they keep a local cache of the recently written data on their local disk so that we can reduce the amount of times we have to access shared storage. And so we have the file system cache that we call the depot on local disk of each of these nodes and then a buffer pool that's caching the data in memory as well. So that's a bit about how we changed our design after realizing that having different sort orders for the buddy projections didn't work well for our customers who are storing large fact tables. There have also been a lot of changes to the hardware that Vertica runs on. When Vertica was first year, we were running on local disk. Now, as I said, we're running on shared storage and caching on local disk. All of our customers on the early days were running on bare metal. We didn't support anything else at that time. And now our new customers are more likely to run in a virtualized environment, either a public or private cloud or VM of some sort than they are on bare metal. CPUs, the cores, the frequencies are no longer getting faster. In some instances, beefy machines have slower cores, but they have more of them on a die so that the overall compute power is increasing, but the performance, the clock speed of an individual core isn't increasing. So we've had to change our scheduling and our threading model that we use within our execution engine. And networking, either because of hardware changes or because of... Can you talk a little bit about the scheduling changes you guys made? Yes. So we used to depend on the OS thread scheduler and we would create a number of threads that were roughly equal to the number of cores on the box for each of the plans that we were executing. And then we would depend on that to give us reasonably good parallelism for that query execution. And now because the number of cores is significantly greater, at that time there would be 8, 16, maybe 32 cores on a box. And now we're seeing machines with significantly more cores on the box and so we're more careful about how we do our thread scheduling. We now handle it within the software instead of depending on the OS. Did you originally depend on the OS because Vertica started off as a focused Postgres and that's what Postgres does? But at that point, before you did this major rewrite, you guys have already removed that process worker per process approach that Postgres was doing. Yes. The worker per process approach that Postgres was doing and their use of global memory because they were running in separate processes was a significant headache for the early engineers of Vertica to work around. But this is different. Our execution engine had already worked around that. But we were depending heavily on the operating system thread scheduler and as the number of threads that we were running increased, we then created a process queue and our own thread scheduler and that also gives us more control over prioritization and some other things. We played some games with nice threads and depending on the operating system scheduler to give us the behavior that we wanted but it never really gave us the behavior that we wanted. Lots of different reasons for that. Some of the commands or the operations that you run are exclusive per process memory mapping and so forth and just lacked that fine-grained control over prioritization of threads. Thank you. The other significant change has been with the network layer. Networking has gotten faster relative to CPU than it was previously. We used to be able to depend on networking a bottleneck and now that's not always the case. There was a need to look at the way that we're doing sort and in particular the way that we're doing key comparisons in order to adjust to the changing landscape of the hardware and make our query execution faster. Sort is important as I described. We use it in our data target when we're writing out these ROS files. It's also important when we're doing query optimizations like a group by pipe or pipeline join where we can use the sort order of the projection in order to do the join or the group by efficiently. Especially if you want to do those operations across multiple threads. I'm sure that most of you are aware of when you're doing an optimization you don't have to worry about the sort order. It tends to be significantly easier to parallelize than if you have to maintain sort order and parallelization. We end up doing a lot of things where we take sorted streams, we segment them, do the operations like partial group buys then we bring those streams back together maintaining the sort order doing something like a tournament sort so that we can do them in multiple threads and get high throughput. We ask ourselves could we do the sort faster and in particular the comparison. We compared ourselves to Tencent's Indian Daytona and that was faster than what Vertica was doing so we decided that yes we can do sort faster and set about achieving that. A little bit of background. Data that's transferred between operators within our execution engine. Operators being things like group by join re-segment of the data and so forth. When we move that data between those operators they're stored in blocks that are either row or column major but you can pick out individual cells within those blocks. They're self-maintained. So you might have a block of time stamps that we can then vectorize and send through an expression that might apply a date difference to each of the cells within that block and having that column oriented makes that expression and evaluation very efficient in vectorizing it so that we can get a bunch of operations within a single virtual method call. So in order to do a comparison between each of the values within the key that we're comparing on or that we're sorting by we have to consider the type of each of the column the descending or ascending specification the null ordering whether nulls come first or last within the ordering and then some other pieces of content that are important for finding the values within those blocks like the location of the first row the stride between each of the columns the number of rows and so forth but those first three that are in bold those are inspections that have to be done for each comparison that's made and so with our fifth version of our execution engine one of this being one of the design changes that we were making we looked at how we could do the encoding differently so that we could do a word by word comparison with no access to metadata in order to speed the sort speed the comparisons that we're doing and you know could we push all the logic to do the comparisons correctly to an encoding on the keys and so the goal was to have a comparison algorithm that looked just like the simple bit of code and in fact this is actually the compare this is the exact code this isn't a snippet or a summary of the code this is the exact code for the comparison that we're doing within our execution engine so that works fine for integers that can be packed into words easily enough but how do you make it work for variable length values you know for example if you had these two tuples where the first column in the sort order had close followed by the second column in the sort order close but not the same and then the second tuple that had as the first column in the sort order close but and then as the second column not the same how do you differentiate between these two tuples if you're going to glom them together into a contiguous words you're asking like how did you look at fuzzy matching or what are you asking sorry it's going to be an absolute comparison so in this case what's on the left hand side would come out first in the sort order because the column that contains close would sort lower than close but sorry close but not the same close but not the same that's the example data sorry yes sorry the first column contains close and the second one but not the same and then in the second tuple you have close but and then the second column not the same right and you want to go on these into one contiguous array of words that you can do a fast comparison on so ignoring what we're doing to the first byte in the word right where we're applying this XOR in order to make it compare relative to the null values which we'll talk about in just a second the solution is that for a variable length word you store each of the bytes within the word with and at the very end you store the number of bytes contained in the word plus one if the value continues on to the next word so this allows us to do a word by word comparison of all the variable length values possibly spanning multiple columns and compare it with that very simple algorithm that I showed earlier just a simple for loop with very little branching involved so the key here is that we're doing an encoding to the keys that are going to be compared in order to come up with words that we can compare each word in the array to determine whether the value sorts before or after the other so null values if it's null first which is our default then the null value is the minimum integer value and empty string would become one greater than that and then we'd apply the logic that I described before where we XOR the first value and then store each of the bytes subsequent bytes in the word last byte being the number of bytes in the word plus one if it continues on to the next word by encoding the values prior to doing the comparisons because we're going to do many more comparisons than we're going to to than just one we saw significant performance improvement in this chart higher is better because we're looking at the number of gigabytes of bytes per second per socket that can be sorted and as I said previously before we undertook this redesign Vertigo was slower than both Tencent, Daytona and Indy after doing the encoding trick and applying the simple comparison algorithm that I showed Vertigo became significantly faster this is on a single node comparison between an early implementation of this EE5 encoding and one that was done as recently as this year so that has an impact not just on sorting data to store it in the ROS format as the data target does but also when we're applying a group by algorithm specifically when there are a significant number of distinct values in the group by so the X axis has number of distinct values and the Y axis has amount of time so in this case lower is smaller bars are better as the number of distinct values increases the performance benefits that we get over using this encoding to do the comparisons increases as well and that's particularly important because if you have a small number of distinct values then a group by hash will work just fine you're not going to have to worry about spilling to disk but when you have large numbers of distinct values you prefer to run it through a group by pipe and avoid having to spill to disk any questions on the encoding and the sort comparison that we're doing can I ask you a question quick yes absolutely yeah yeah so how do you handle when you have multiple like called distincts like A, B, C data science guys do quite a bit there may have like 50 of them in there yes so this is remember you do partial and you find also you have to remember a bunch of stuff in order to T2 you do partial group by different nodes but then when you want to define a group by you have to dedupe the columns again because they count distinct not just count yes so you're describing a situation where you are grouping by the same set of keys and then applying a count distinct across so you might group by a symbol but then count the distinct bid and the distinct ask prices is that correct yeah that is your group by column, group by column then you're distinct on other things right right and so what you're applying then is you're doing a grouping based on you know in this case a group by pipe you'd be grouping based on the grouping keys which gave the example of symbol and then you'd be applying a similar grouping to the secondary key which would be the bid and the ask price so you have the there are many secondary keys right yes yes right and so the simple thing to do is to separate those and treat them as separate sub queries and that of course is expensive because you've got to reapply that primary grouping based on the group by key the more efficient thing to do is to do the primary grouping and then apply multiple secondary sorts to the keys that you're counting right and so yeah but the problem is that you may have a huge common sub expression across them because you are creating your common sub expression before grouping which is terrible I'm in sub expression before yeah because I do the join then I have to do group by like the stock symbol common distinct of A and then I do another one for symbol and column distinct of B and so on and so forth so the result of the join has to be fed to all of these guys so unless you have some push mechanism other than that then you have to temp it and then read from the temp of the disasters because it'd be for the group anyway we can I can introduce you to Hamid at first if you want sounds good I'd like to dig into that more thanks Hamid so switching gears a little bit I'm talking about the elasticity of Vertica running in the cloud I need a second to peruse the cartoon and I will mention that Vertica does now support running in Kubernetes as well as on all the major cloud vendors so a couple of use cases that we've seen from our customers over the years for why having elasticity which is akin to running in the cloud either public or private was important to them some of them have a bursty workload one example that is a follow the sun model where your workers in Asia are busy at different hours than your workers on the west coast of the United States and so you want to move resources around in order to accommodate those data analysts in the places where their where their sun is up another is that customers don't want to throw data away they wanted to keep it around forever and so they had a very long tail of historical data but they would are typically querying the most recent data in the database so they want their compute to be independent of the amount of storage that they have they might be querying this month's data but they've kept data around for many decades another reason that is very straightforward is if everything else is in the cloud if you put your other applications there so that they can be scalable then you want your database to be close to those applications and so you want your database to be in the cloud as well and another very pragmatic reason is that justifying op-ex is often easier than justifying capex especially when the difference between them can be significant if you want to run an experiment do a skunk works project or hackathon project in the cloud it's easier to get approval for spending several thousand dollars over a couple of months than it is to get approval for spending hundreds of thousands or millions of dollars on hardware just for an experiment so keeping in mind some of our design principles especially those for MPP scale out and distributed query I mentioned before that Vertica is careful about how we place the data so that we can do co-segmented joins co-segmented group buys don't have to utilize the network to re-segment data among the nodes and the database if we stored it in a way that the grouping or the joining can be done independently on the node so here's an example where if I create a projection for my customers table and I segment the projection by the hash of an ID on all nodes and then I create another projection for my purchases table and I segment by the corresponding customer ID key now when I do a join between those two tables there's no need to shuffle the data between the two nodes so I'm joining on the keys that I segmented the data by I can do the join local on each of the nodes and then process the results and send them back to the initiator so that makes that careful placement of the data makes elasticity challenging in our eon mode architecture instead of calling it segments we call it shards but the design is that nodes are assigned to shards and though the data is stored in shared storage the shard that they're responsible for processing is determined by the subscription and the shard that they're storing in that local cache that we call the depot is also determined by that shard subscription so if we started off with three nodes and we had three shards to begin with each time a query is executed all three of those nodes are participating in it if we double the size of our cluster then we have a challenge because we've only got these three shards but now we have six nodes that can do compute on top of those shards for new data the solution is relatively easy for new data we can just write it down so that we segment the data in a way that's optimized for the number of compute nodes that we have if we were to take away three of those nodes then we'd have an assignment where for the new data each node would be associated with two of the shards one A and one B the older data it's a little bit trickier that's already been written out it's already contained in storage containers that group things together based on that segmentation so we have two ways of dealing with what we call elastic crunch scaling which is when we're going to apply multiple nodes to the same storage containers one is that if we don't care about the segmentation then we or sorry this is the other case when we do care about the segmentation then we can have those two nodes so in this case one and two that are reading from shard one they can apply a filter where they're reading just half of the segment's worth of data so they're both doing the same amount of I.O but they're applying a filter so that they're doing compute on only half of the data and this works well for compute intensive tasks obviously it doesn't provide a significant win for anything that's I.O. intensive the other approach that we can take is to store this data in multiple storage containers if we don't care about the segmentation of the data or if it's very I.O. intensive then we can separate those storage containers and distribute them reasonably uniformly to each of the nodes so that nodes one and two in this instance are reading from different storage containers they have the same segments that they're processing and so if we care about a co-segmented group by we don't care about the data between the two of them but this works well for workloads that are I.O. intensive Any questions on those two different approaches? Alright and I think that was all the material I had prepared for this talk so there's you're probably already aware you can go and learn more at vertica.com you can try it for free that link takes you to our Vertic Accelerator which is our as-a-service offering it's just easy to spin up and get going with and then of course we're always hiring so you can find job listings at vertica.com slash careers I'll pause and have everyone else open up to the audience and Matt would you want to go first? Yeah thanks Stephen for the talk just a quick question so when you talk about these cloud deployments are these nodes typically homogeneous or do you see a mix of instance sizes within a single deployment? Yeah I'm really glad you asked that that's a great question so we have this notion of a cluster which is the entire database and then within a cluster we have subclusters which are you might have a subcluster for doing your ETL jobs and maybe that has to be big and beefy so you have 64 nodes in that for your ad hoc queries maybe you don't care as much about the performance so you have 16 nodes in that subcluster for your dashboarding queries you might have many of those subclusters for dashboarding that have relatively few nodes maybe four or eight nodes in each of those within a single subcluster so those should be homogeneous because they're doing work together right and you're only going to be as fast as your slowest member of that subcluster so those should be homogeneous between subclusters though they can be heterogeneous so that big beefy ETL job that you have to run maybe those 64 nodes are big expensive powerful machines maybe for the ad hoc query or for your machine learning workload you have where time might not be as important you have less beefy machines does that make sense? yeah perfect thank you yeah it's a great question I'm glad you asked that I mean you've got one okay I actually have two questions so one is the follow up to the previous question so when you have different subclusters do you also cache the data independently? yes the data is cached independently and that's a great question because the query workload might look very different across each of those yeah okay good makes sense so the other question I have is that have you compared with the cloud native engines such as the Rimeo how close they are to you because they're all chasing you anyway I mean chasing the classic databases so how close are they? I would say also too that the database guys announced last week they hold the TPCH record yeah okay yeah yeah Rimeo we haven't done comparisons with recently mainly because we don't see them very often in our field when we're doing proofs of concepts we've done some comparisons with other cloud native databases Snowflake relatively recently where we showed that we had especially when it came to throughput significant advantage in performance and especially in cost for performance okay so that was a price performance comparison or just the pure throughput comparison? it had both elements in it what we found is that when scaling up the number of concurrent queries that performance in Vertica was significantly better so how big of a database did you have over there if you can't talk about it? this was done by a third-party contractor I can look for if you look for search for midnight and Vertica you'll probably find a comparison that I'm speaking of or if you go to Vertica's website I believe there's a link for downloading that as well okay any other questions from the audience? I'll ask one more can you talk a little bit about how the catalogs are stored like how things have changed from obviously Postgres what 15 years ago or something like that but have you moved to a different database system entirely or should it be used for some systems to store their catalogs or is everything in-house? everything's in-house the catalog has several really neat properties to it it also has a couple of pain points it's relatively bloated it is that's everyone's catalogs but it does have some great properties of consistency guarantees it's really interesting particularly when distributed queries we have this mechanism for reference counting the catalog keeping versions around because my query that I initiated might be running on a different version of the catalog than the query that you initiated just a fraction of a second later each of the nodes their catalogs are advancing at a different rate than are perceived by the query if that makes sense so when I initiate my query I'm looking at a catalog version but now when it gets distributed to the other nodes in the database they have a different version of the catalog we need to make sure that everybody has at least the same version as my initiator there's a lot of interesting stuff going on in terms of the catalog in a Vertica database my last question would be have you guys noticed any sort of major trends or changes in how people are using Vertica now that's the cloud service versus when it was on-prem it made this hard to know because you don't have the visibility to see how people are using on-prem Vertica as much as you do in the cloud so I'm asking is there any high level things like oh people do their queries are shorter queries are longer any sort of major trend like that or are people stupid are people dumber on the cloud to get through the process of running Vertica on-prem you had to go through procurement and talk to people who knew what they were doing now you just give Vertica your credit card and you're up and running well it's definitely one of our challenges to offer excellent performance that's also easy to administer and I don't know that that's unique to the cloud because it was valuable to have DBA expertise those are limited and it's not always the DBA who's optimizing performance of the database application developers are creating tables and projections and so forth and so that's been one of the challenges is both identifying instances where a projection could be rewritten to be optimized for the query workload that's being run against the database and also making it easier for those optimizations to be applied because we no longer in the early days you had somebody that was working with sales engineers at Vertica somebody who was an expert on the Vertica system they'd learn how to optimize projections for the workload and they'd curate their Vertica database and now many of our customers have a lot of different users on the database who don't have that Vertica expertise maybe the question might be like is there a sequel functionality or feature that you guys do not think was a high priority when it's on-prem but now that you have observability to every query that's been executed on the cloud you realize it is something you guys need to optimize so our cloud deployment model is a little bit different it's that we deploy within the customer's own cloud account so we are able to administer the database we can't see some of the queries but we're not observing it


A huge win for the Indian Superstar, Pragananda scores an absolutely thrilling victory against former world champion, Wesleyan Toppeler. He joins us in our studio. Pragananda, firstly a big congratulations on this win against Wesleyan. I think. I have to ask you, is this your first time playing against a former world champion in a classical time control? Yeah, I think so. This is my first time. For now I don't recollect any game, but I think it's the first time. Rapid and Blitz, you've played in Tata Steel. In Tata Steel. So how was the preparation for this game when you got to know you're playing Wesleyan, what was the preparation like? Yeah, it was tough to guess where you will go and yeah, I was looking at some lines but I was not looking at this 9 of 6 classical line. So I was just playing on my own. Like I knew some things, but what he played I didn't know that. Right. So at this point I went for Bishabhi too. And he was playing quite fast. Yeah, he knew till this point. And yeah, here I took long time. I was just thinking something like F5. Let me just put that for you. F5 and it doesn't work actually. Even EF5 was possible that that's what he suggested. 9 d5 just 9 c6 c2. But I was mainly worried of Bg5. Yeah, if let's say queen d3 then I think now EF5 was even stronger. Or even some Bb6. But I was considering Bb3. Bb3, Qe3, d4. Now let's say Qf3, dc3, Qa8. Yeah, then first I was thinking Qd4, but then I thought just cb2 was even stronger. Let's just get stuck sometimes. Yeah, Rd1. Yeah, Qc7. And you evaluated as black being fine here. Yeah, it's like now it's the thirdest, nicest Bb7. And I need to bring my queen and EF5, Bb6, c6. And the pawn is still alive on b2. Yeah, I will take care of him. But then he will get E5. E5 pawn. Yeah, it should be good for black. Right. And you took a good 35 minutes for this. Yeah, I don't know why I took so much time. I mean, first of all I was thinking even 9 d1. Like he said, 9 d1 was the Indian solution and maybe it was just should be around equal somehow. So 9 d1 was his prep. So you surprised him. And after Bf2 is the first time he actually started taking some time. Yeah. And yeah, I played Bb6. Also 9c6 was I think even possible. Yeah, I played Bb6. No, but I think black should be fine after 9b4. That's what we analyzed. Just go 9c6. Okay, so reroute the knight. Yeah, there's no much attack for me. But I think EF is kind of a mistake. Right. Because I just get my knight to d5. Yeah, play c4 next. So after EF5 did you feel your positions better? Yeah, of course like here I didn't like now I don't have much attack but it's somewhat I can create some attack. Right. It doesn't feel there's much. But after EF and 9d5 now I think like maybe even already I'm better. And here he went knight b4. Yeah, then just c4 and rook c8 a3. Yeah, he can take cd5 and bishop c5. But I mean here just some rook d1. So you keep these two central pawns and... Yeah, I just played d6 and even just exchange rooks. It looks very pleasant for white. Yeah, it should be better. After knight c6 I just played rook f1. Yeah, here we were trying some rook a8. But just rook a d1 was just stronger. Say if some bishop c5 or queen f4. How? Okay, bishop f2. Yeah, I can do it. And then on knight f6... This knight f6 was a threat throughout. It's in the air once your knight is posted on d5, no? Yeah, it's not easy for black to play these kind of versions. So ef5 was a surprising decision by Wesleyan. Yeah, it's just better for white. Knight a4, not so good I think. Just rook d1, I mean it's dangerous for black. So here he can't take on c4 because you just move your queen to f4 or...? Maybe he can take but I was just thinking queen e2, queen e6. It looks dangerous for black. Right. Maybe there's something even better. Even queen f4 was... If queen a8, then some knight f6 might be there. Yeah, always in the air. Yeah. And then this happened very quickly after this trade here. Yeah, here I think queen h4 might be important because... I'm... It's not easy for him to do anything. If queen a6, then knight f6 comes. Anyway, you've got this because if you take and now it's the same idea with the queen attack. And if he goes king a6, that was thinking like it's a main trade but then rook d1, queen a6... Let's try one. Knight a4, yeah. He can't take queen c4, knight g6 comes. So you win the queen here? Yeah, I was thinking queen a7. First I was... Let me try it. Yeah, I was thinking queen g3, like knight e5, then rook e5, knight g6 comes. Oh nice. So always there are these tricks of winning the queen. But I didn't like... I didn't like queen g3 because he goes rook fd8. Trades off. Because he was thinking like rook d5, if he takes then cd5 but knight d4 was... I like he goes knight e6 then c4 a7. So he stabilizes somewhat here. Yeah, but queen a7 is a good trick for the... And just a6. Let me raise this. He also told this one it's just good for white. I mean if rook c4. Yeah. Or then ef7, of course. So you can't take on f7 and knight e6 is coming next. Yeah, it should be winning somehow. Even queen d8 whichever surprise was because knight fd8 just wins. Yeah, so queen d8 is just... And he took 14 minutes. Yeah, he missed knight fd6 and rook d1. Completely missed this... I mean I'm sure he saw knight fd6 but this idea of rook d1 was probably... Yeah, maybe he missed it, I'm not sure. Because the point is that you can't take instantly because of this queen d4 check. Yeah, after rook d1, I'd say queen c7, ef6, king h8. Then I thought rook d3 was more precise because if he goes rook e8, yeah, rook e8, then rook h3 and he doesn't have rook e1 check. Because of the queen on h4. Yeah, even with the rook on rook d1 check shouldn't be like much problem. Yeah, this is just precise. Knight e5, take the queen f6, knight g6. Yeah, here I can just play slowly but I saw this line h4, h5. But this is very nice because you went for a direct line here and your idea of course if he doesn't play h5 is to just start threatening mate. h5 was forced and rook f1. Here f4 was kind of a first move because... Yeah, I just win f5 pawn. Oh, g4. Did you see g4 when you played h4? Was this your... Yeah, I was starting from here because I mean this looks forcing. Yeah, and he can't take fg3 because of the f75. Yeah, if hg4 then h5 comes. Even rook d3 works. I mean it's kind of a main thing because... And also here if rook d3, hg6 I'm actually in a king time but there should be some other way to win but I can just go king d2. Yeah. Then rook f1, queen h5. Let's just have that. On the board. Very nice. So you saw this whole variation on the board. Yeah, also rook d3. I mean I need to see this one. King f2, rook c4. Yeah, that I just ran with the king. It's sort of problems. Yeah. Rook c2, king e1. Okay, and there are no perpetuals. Yeah, I took here. And it just collapses because now he doesn't have enough material to defend. I just go rook e1. It is only... A nice game also. A nice result but also a well-played game. Yeah, I think in the opening I didn't play so well but after the opening, like after e5 it was okay. Brog, now you lost the first game and after that you had five wins in a row. What's going on? I don't know. I'm just like playing one game I think. Right. Well, thank you very much and before you go I have to ask you that now there are... We've crossed the halfway mark in the tournament going into the last four games. You're one of our leaders at the event currently. Are you thinking about that or just going to continue with the strategy of one game at a time? Yeah, there are more four rounds. I mean still it's not clear that I'm a leader but at least I'm at five points. In the top back, five out of six you have to be happy with that score, Brog. Yeah, it is good. All right. Well, we really enjoy having you in the studio telling us our games and we look forward to more. All the best for the remaining games. Thanks, Frag.


Hello, welcome back to my channel, or welcome if you're new. I am so excited. This is my first, like, non-vlog, my first get ready with me that I'm doing in this bathroom in the new apartment. If you've already been watching me, if you compare this to what I would film in my bathroom in the old apartment, such a difference. This is so much better. The lighting, incredible. If you are new here though, hi, my name is Sam. I'm just gonna be getting ready and completely overshare and give you all the tea about my relationship because I shared a couple months ago that I got back together with my ex-boyfriend and I shared a little bit like here and there, like on my podcast and on this channel, but I never like just sat down in one format and just gave like the full details from start to finish.  How did I miss this? What's going on? Also, if anybody else is going through something similar, I know throughout the last couple years, like figuring things out with him, I was really looking for people to relate to that had been in a similar situation because it's tough.  Like, don't do that. That's a bad idea. They're an ex for a reason, like you broke up for a reason, but sometimes that reason is not always because they were a bad person or you weren't good for each other. Sometimes it's just like, you both have things you need to work out on your own separately or it's not the right timing or whatever. Before I get started though, I do have to give a quick shout out to the sponsor of this video, dossier. If you know me in real life, you know that this is a staple for me. I'm a big fragrance person. I always need my home smelling good. I need to always smell good. I go through perfume a lot and dossier makes replicas of designer brand name fragrances, but they just give it a different name, put it in simpler packaging and you can get it for a fraction of the price. So rather than paying like $200 for a perfume, you can pay like $30. It's like, it's a no-brainer. And I have a few favorites from them. My go-to that I have been wearing, it's been like my signature scent for a couple years now is the Amberie Saffron, which is a replica of the Baccarat Rouge 540, which is very expensive, but it's like a quarter or less of the price from dossier. And it smells amazing. It lasts all day. I get compliments constantly, but what is very exciting is they recently launched their discovery set because I get messages from you guys asking like, what are your favorite scents? What do you recommend?  And like fragrance is so specific to each different person. We all have different preferences and depending on how it mixes with your natural pheromones, it can smell a little different person to person. So the discovery set is so awesome because you get 10 of these smaller sized bottles.  I think this would make a really great gift for one person or you could honestly get this and then divvy it up and like make a little gift basket and include one of these for 10 different people. I just think it's such a cool idea. And in the discovery kit, you get seven inspired fragrances and then three dossier originals. And they do have ambrose saffron in here, which like I said, is my favorite signature scent. So if you'd like to check out dossier for yourself and get the discovery set, I will have a link and a discount code in the description. And thank you so much dossier for sponsoring the portion of this video. I already put ambrose saffron on today, but I'm gonna give myself one more spritz. Why not? So I guess I'll just start at the very beginning, like how me and my boyfriend met because I really love this story. And comment down below, let me know. If you have a partner, I would love to know how you guys met because I love hearing these stories. But I was going through like a weird transitional phase in my life. I had just got out of a really long relationship where we were living together. We had been together since high school. It was like first serious relationship, first love type situation. And I ended that relationship, moved back home with my parents, enrolled myself in cosmetology school. Like it was really, I was just like starting completely fresh. And I was not focused on like getting into another relationship or meeting anybody else. So one day, like a couple months after I had moved back home, he was my brother's friend and they had went to school together, but they didn't really like hang out. They weren't close friends. When they were still in school, they reconnected a few years later after they graduated. They were working together and like had mutual friends and stuff. So after I had already like left, I was no longer living at home with my parents. They became friends. They started hanging out regularly. So I wasn't aware of this friend. I was sitting on the couch in my parents house and I was like in my pajamas and my robe, had my glasses on, hair was a mess. And I was just watching TV with my mom and this guy walks through the front door and I was like, who is that? The funny thing about it too was my mom and I at the time were binge watching the show Shaneless. And I remember saying to her, oh my god, Lip, one of the characters on the show is so hot. Like there's just something about him that is, oh my god, like I have the biggest crush on him. And my boyfriend resembles him a lot, just the way he like carries himself, the way he dresses and stuff. And so when I saw him that first time, I was like, this is insane. Like I was just sitting here talking about how I have such a crush on this guy, this character and his doppelganger like just walked through the door. But my brother is younger than me and so is my boyfriend. And so at the time I was just like, oh well, he's just like my younger brother's hot friend. I really didn't think anything of it, wasn't planning on pursuing anything, because I was just like not really wanting that at the time anyway. And also like he was younger. But I would find myself like looking forward to whenever he would come over to the house to hang out with my brother. And I remember at the time I had saw this meme that I thought was so funny. It was basically saying like, oh me at 27, I'm just hoping my soulmate will walk through the door and find me sitting on my couch. And you know years later looking back and like that is basically what happened. Like I wasn't looking for anyone. I was literally just sitting on my couch at home in my pajamas.  And the other thing that's funny about it and that I think just makes it feel so like meant to be is he had met my dad at the gym. They were both working out at the same gym and they would go around the same time and they would work out together I guess whatever. He didn't know my dad's last name. So he didn't know that my dad was my brother's dad. So he was friends with my brother. Didn't realize that like there was that connection. One day when he was at the house hanging out with my brother, he saw my dad and it was this whole moment like, wait what? What are you doing here? How do you know? Like and then you know I ended up moving home and then he met me and it just kind of felt like well if I didn't end up meeting him through my brother I might have met him through my dad. Like it would just felt like it was just meant to like he was just meant to be a part of my life you know. So anyway he would just be at the house all the time and I would just refer to him as my brother's hot friend. Didn't know anything about him. And then months later I had started dating a little bit here and there and I was seeing this guy for a little bit and he just turned out to be a total fuck boy and I went to my brother's room the one night to go like vent to him and ask for like guy advice on the situation and his friend was there and so he was getting all this advice and he was just like being so insightful and just honest with me and I don't know it was just I just loved like his maturity and his energy like that was really the first time that we really had a conversation and then anytime I would see him again at the house he would ask me updates like oh so like what's going on with that guy did you try what I suggested and like the more I would talk to him and just be around him I was like I am into him but is this weird because he's my brother's friend and like he's younger than me I don't know so then fast forward another couple months later my brother invited me to a New Year's Eve party that another mutual friend was having and that's when like the sparks started flying you know we were like drinking we got really flirty and we just ended up hanging out that whole night we had exchanged numbers or snapchats or something and then he ended up texting me like the next day and from there we were just talking non-stop and then we started seeing each other very casually he actually ended up coming to my cosmetology school because it was like the last couple months before I finished school that we started seeing each other and he came to my school and he let me get some of my last few credits done on him I like gave him a manicure I gave him a perm and a haircut like a bunch of stuff and just seeing the way that he was at my school and like with all of my friends at school and then of course after that all my teachers and friends at school were like oh god who was that guy he's so cute you guys are so great together oh my god blah blah so just the more time we would spend together like we both just really started falling for each other more and more it was like in the beginning I just wanted something like casual and innocent because I wasn't sure with our age gap he's six years younger than me by the way I always envisioned myself ending up with someone older than me for whatever reason also my brother was not happy at all with us getting together to put it lightly so I didn't think like oh this is gonna turn into anything serious but the more that we got to know each other we just are so similar at our core and it was interesting because I felt like any other time when I would first meet a guy you know there's always like that pressure you always feel a little nervous like oh I don't want to come off the wrong way or like embarrass myself or you know you want to make a good impression but with him from day one immediately maybe because he already knew my family and so it just felt comfortable I don't know but I immediately just felt like I could completely be myself and like let my walls down it could even also be the age gap thing because I was the older one maybe I didn't feel like I had to impress him I don't know but there was just from day one like this comfortable feeling of like we're just on the same wavelength you get me I don't have to filter myself in any way that was just so refreshing there was a lot of emotions that I experienced and I was like I've never felt this way before and I didn't even think that it was really actually possible to feel this way about somebody and just things he would do for me that I was so not used to like he would just be so sweet and consider it and like on his way home from class he would stop at my job and bring me a coffee without me even having to ask and I will never forget I stayed the night at his house one time and it was in the winter he literally got up early so he could go clean the snow off my car and heat it up for me as I was getting ready I didn't ask he didn't tell me he was gonna go do it like he would just do it like just sweet thoughtful things like that that I was not used to at all because in my previous relationship that would be stuff that I would ask for and I would just get met with like can you just do it yourself do I have to like shit like that it's like come on can you show me you love me and do something nice for me for once and like without me having to ask to you know so it was just a big change for me and I was head over heels like completely infatuated with this man and I really was convinced like we are soulmates we are going to get married like this is it for me this is my person I cannot believe that we found each other and that he exists like he is my perfect person oh my god I've never been so happy amazing and then I don't know life just happens he was in college at the time and just trying to figure things out he wasn't super committed to a specific major he changed his major a few times I was just trying to figure out like what he wanted to do career wise which I can personally relate to but it was just a little bit frustrating because due to our age difference I was at a point where I was like okay I was like starting to get established with being a hairdresser and like YouTube was doing well for me so I felt like okay I'm getting established in my career but you like don't even know what you want to do as your career like you're still totally lost and I was trying to be supportive but I think I was just getting like impatient and kind of frustrated at times because I don't know I was just at a point where I was ready to like start settling down and he just wasn't there yet and I think I probably put unnecessary pressure on him that wasn't very helpful and then the pandemic happened he just got to a point where he was very depressed and I mean I can't even imagine like the pressure of that of because like I said I've been there I also struggled and like changed career paths and had my moments where I felt very lost and just didn't know what I wanted to do with my life so I get it but I can't imagine going through that and then also being with a partner that's like pressuring you to figure it out and then also going through a pandemic and you know all of the changes that were coming along with that and you know he had like family pressure and stuff too so I don't know I I've done a lot of self-reflection and self-work during the time that we were broken up and I definitely because at the time I think I was just immature too and you know I just was convinced that I'm never the problem it's always everybody else but now looking back I can understand where I contributed to like the problems that we ended up having in our relationship I don't know it was just kind of a tough time and then we had moved in together I think at that point there was already a lot of like resentment from both of us and we were just fighting a lot and he was just really depressed and struggling to find motivation and I felt like I was the one pulling all of the weight rather than being supportive like I should have been being more understanding I think I was just like making things worse by being kind of mean you know like we both are to blame for sure but it just it just got to a point where I felt like okay we really need a reset here because like I love you so much and I think that we are so good together and so compatible in so many ways but like we cannot continue with things the way that they are and like I don't see us getting out of this because like we would have a couple of good days but then something would happen that would like trigger an argument and then like all the resentment would come out and it's like all this stuff was just kind of built up and it was like okay this is not healthy and I just at the time wasn't really happy with my life in general like I just wasn't happy with where we were living like I was just so sick of being in that town because the time we were living in was the same town where I grew up most of my life and went to high school and all that and I had left a few times but kept coming back and I never wanted to settle there and it got to a point where I just felt like I'm going to get stuck here if I don't leave soon I am going to get stuck here and I can't keep doing this like this cycle of like me saying here I'm not happy waiting for someone else to like finally figure out what they want to do with their life so that we can then move on I felt like I was putting my life on hold waiting for someone else I kind of felt that way in my first serious relationship too and I was like I don't want to do this again like I need to stop I need to stop waiting for other people like I need to live my life for me you know and he needs to figure this stuff out on his own without me there breathing down his neck pressuring him because also like I don't want him to jump the gun and decide something just because I'm pressuring him and then not be happy and resent me later on and feel like he was only doing something for me because of me and I felt like by me staying there like I was resenting him because I felt like he was the only person keeping me there at that time so I moved to North Carolina this by the way Pennsylvania is where I was living where I am from originally so I moved to North Carolina by myself me and my dog and we decided that we were gonna just break up at that point but I think that we both kind of knew and were hoping that we would find our way back to each other at some point but there was no like promise or guarantee like that wasn't something that we were specifically planning on it was just kind of like well this is where we're at now we just need we need space for each other to figure things out and we can reevaluate at a later point and you know like I felt like I wasn't shutting the door completely I was I was closing it but like keeping it a little cracked and it was really rough because I missed him a lot but I also knew that like where he was at and the way we both were in that moment like we couldn't work it out like it just was not the right time so it was kind of bittersweet but I also I was excited I was okay I'm moving to a new place I can meet new people I'm gonna start dating I'm gonna see what's out there and like I'm just gonna let the universe take control and if I'm meant to meet someone else and be with someone else great if he is my person and I'm meant to end up with him great so I dated I got you know I downloaded all the dating apps I put myself out there and I met some guys that were really nice it just I just didn't feel right and then I met some guys that were just like it was very bad and I just felt like every time I would have a conversation with another male whether it was like a romantic flirtatious conversation or just completely platonic and casual like it just constantly made me think about my ex and I was comparing everything to him and it was just making me realize and I had wrote down a list because my therapist suggested write down a list of qualities that you're looking for in an ideal partner have like your deal breakers you're nice to have so I did that and I would go on these dates and I look okay some of these guys were like checking off all the boxes on paper I looked great on paper but I just wasn't into it like there was just not that chemistry there was not that feeling of like you get me and it just made me realize the connection I have with my at the time ex was so special and so hard to find it just made me miss him so much though like he would get this joke right now like this guy is looking at me like I'm nuts but meanwhile my ex would be like on the floor dying right now we kept in contact we were broken up for about two years almost two full years and throughout that time we still stayed in contact anytime I would go up to Pennsylvania to visit my family I would see him and every time it was kind of like oh okay maybe we'll get back together like maybe maybe things will work out but each time it was like okay we're not there yet we're not ready yet there's we still there's still work that needs to be done and uh I don't know so he saw other people I saw other people we just kind of we stayed in contact and we still like knew what was going on with each other's lives we still stayed friends but we weren't like you know talking every day or anything and we're just doing our own separate things living our own separate lives and he started going to therapy I was doing therapy a little bit here and there and talking it all out with friends and really starting to like pay more attention to how I treat people in my life and then eventually over time things just got better and we had a lot of talks like really long heavy conversations emotionally heavy conversations and we worked through all of the stuff from our past I finally felt like we were at a good point and he before I had moved away he had changed his major and the entire time that we were broken up he stuck to that and ended up discovering that like that is really what he's passionate about and he went from not really putting in a lot of effort to school like not being super motivated or passionate to finding what he really loves and he made the dean's list was getting amazing grades and I could just see like such a change in his overall like attitude and I definitely had an overall change in my attitude as well and it was just so good it's like we needed that time to be a part to work on ourselves as individuals and become our best versions of ourselves he's calling me right now we have such strong chemistry in so many ways like we like all the same things but then we are different in certain aspects where we kind of like balance each other out and kind of bring out the best in each other I think like the age difference just kind of threw things off a little bit and just like the point where we were both at in our lives I don't think that I was mature enough to be a good partner when we were dating and I mean they're still to this day like there's still stuff that like I'll say or I'll do and then we have conversations and I'm like why did I do that like that was just immature and dumb and stupid like I don't know but one thing that I really love about him too that I think is like so special and invaluable is he's always been such a good communicator and so open to like talking things out like if something upsets him he will communicate with me rather than just like getting mad and starting a fight or if I'm upset and I approach him about something like he's always willing to talk things through yeah so things we're working out we were at a point where we were talking every single day and we were talking about the possibility of getting back together or working on getting back together that's what we both wanted but you know it was a little nerve-wracking because I didn't know it's hard when you're not able to be together in person because I feel you can talk on the phone and things can seem fine but then when you're like actually together in person every day living together like doing life together that's when you face obstacles and then he came to visit me at the end of summer it was kind of like a test run to see like okay are we really there like did we really complete the work that we needed to do like are we at a point where we can get back together and it was a really good trip he was here for like two weeks I think and then a month or two later I went up to Pennsylvania and I stayed with him for about a week that's what I was a little worried about was like well being back in the house where we lived where our breakup happened where you had like there's just a lot of triggering things in that location and just like that town in general it's like being down here and going to the beach and doing all the stuff it's like we're kind of on vacation so it's easy to like be in La La Land kind of but me going up there was really like the true final test and it was just so good and it was such a relief because it was like finally all of like the good things all of the love that we have for each other is there like the resentment is gone like we worked through all of that so we've seen each other a couple more times since all of that and we decided a couple months ago to officially get back together and we're long distance right now which sucks but it's temporary he is finishing up he has his last like semester and a half of school then the plan is for him to move down here I'm very happy with where we're at in our relationship we've talked about the future and our plans and what we want and we're both completely on the same page and we've talked about everything like all of the possibilities and like well what if this happens what if that happens just to make sure that we both truly want the same things like I said I just left it up to fate and to the universe I didn't want to force anything one way or the other and this is just how things naturally worked out and I know people were asking if he is going to move into this apartment with me I don't know that's to be determined because who knows in a year from now if the rent goes up a lot like I don't know if I'm going to stay here for longer than this year and he's not going to be done with school till December so by the time he's down in school and moves down here the lease on this apartment is going to be up soon so I might stay here and he might live here with me we might move out and get a different place together I'm not really sure so that's why moving into this apartment if you've been watching my moving vlogs every step of the way like I've been on FaceTime with him getting his input but I'm kind of making it my place for now and then we'll just see once he comes down here what ends up happening what adjustments we need to make whatever but that is the story with that I obviously don't want to encourage anyone to get back into a relationship that's unhealthy or you know get back with a toxic partner because I truly think that sometimes when a relationship ends you miss your ex sometimes and you only focus on the good things you only remember the good times you forget about the problems you had and there's that comfort in that person that you were with especially if it was for a long time so you know it's easy to have feelings if you're like oh I want to get back with them and but sometimes that's not what's for the best if that's the case for you I don't want you to like look at my story and be like oh well she got back with her ex I'm gonna do the same but if it's a situation of like just bad timing or you know and you're both doing the work and there's effort from both sides to make the relationship work and it just feels like it's the right thing and like it's what's meant to be then I say go for it like relationships do require work because like for human beings like any even our friendships it requires effort and sometimes you'll have bumps along the way but that doesn't always necessarily mean that it's not the right thing sometimes it's right person wrong timing so yeah that is the tea about my boyfriend and our situation so let me know if you could relate to that at all and if you are just looking for someone to talk to you're kind of like struggling in a similar situation trying to figure out what you should do feel free to reach out to me or you know leave a comment and kind of get a community everybody can kind of weigh in with their experiences I hope that you guys enjoyed this video don't forget to check the link and discount code in the description for dossier I appreciate you watching and I'll see you really soon in my next video bye