David Masri is Salesforce Architect, Data Architect, 9x Salesforce Certified, Certified Google Data Engineer, Director of Professional Services at Plative.
David joins to talk about the difference between Salesforce data migration and integration, their best practices, record locking issue among many other points from his book.
Sponsors
This episode is sponsored by FormAssembly.
22 Ways to Use FormAssembly for Remote Work Success – Learn how to streamline remote work processes with FormAssembly’s all-in-one form builder and data collection platform
Links
- David’s LinkedIn
- David’s book – Developing Data Migrations and Integrations with Salesforce – Patterns and Best Practices
- David’s personal blog
- David’s data locking article 1
- David’s data locking article 2
- Best Practices for Deployments with Large Data Volumes
- Managing Lookup Skew in Salesforce to Avoid Record Lock Exceptions
- The Salesforce Bulk API: Maximizing Parallelism and Throughput Performance
- Force.com Record Locking Cheatsheet
- Salesforce API Series: Fast Parallel Data Loading with the Bulk API Webinar
Video Teaser
Contact Me
If you enjoy this podcast, please reach me out to let me know your thoughts or simply say Hello. My (Xi’s) contact info:
Take care, until next time :)!
Transcript
AI-generated, unedited.
[00:00] I'd like to welcome our sponsor Form Assembly. You can find out how Form Assembly helps streamline remote work processes in the free ebook that we've linked in today's show notes. Form Assembly's all-in-one web form platform lets you create forms for just about any use case, from contact forms to donation forms, all while take advantage of useful features such as notifications, e-signatures, and more. Not only that, but you can also connect data to systems you already use. Form Assembly integrates with Salesforce, PayPal, and many other common solutions. Whatever your data collection needs are, you can be sure that Form Assembly keeps your data secure with encryption at rest and in transit on all plans, plus compliance with GDPR, CCPA, and more regulations. At the end of the day, form assembly helps you save time, money, and effort while getting the maximum benefit out of the data you collect. And I remind you, when you support our sponsors, you support the show.
[01:20] Hey everybody! This is Xi Xiao. This is yet a new episode of Salesforce Way podcast. Today, I am sitting with a new guest. His name is David Masri. Hello, David. Hello, Xi. How is life? Yeah, things are good. Can't complaining considering everything's going on in the world. Happy to be healthy, still have a job. Yeah, thank God. That's that's good. So David, would you like to briefly introduce yourself? Sure, absolutely. So my name is David Masri. I work with a company called Plaitiv as the director of professional services. Previously, I worked at Cap Gemini. Over there, I ran their data team within their Salesforce practice. So there. Director of Data Strategy within their Salesforce practice. I recently authored a book, Developing Data Migrations and Integrations with Salesforce. So I do a lot of data work in the Salesforce ecosystem, integrations, data migrations. Been doing this for about five years, but before that, I had a really, really strong data background coming into into the Salesforce world. So it was really great opportunity for me to you know take all of that traditional data knowledge and traditional enterprise systems knowledge, and then kind of apply that to you know working Salesforce world. So our listeners won't have the chance to to see the book that you're showing me on the screen, but I will put the link in our show notes so they can hit the link and you can check what the book is really about. So at least from the title, it's quite obvious. It's the Salesforce integration and
[02:50] the Salesforce migration, right? It's two big topics, and that's also the reason we're here chatting about this. So our conversation is usually about thirty minutes only, so we won't be able to cover the full book. And that's also the reason the listeners could go and buy a book. So because I do sometimes more the integration part, which is also more interesting to me. So let's briefly talk about what's the difference between integration and migration. So I naively think migration is just one-time job, while integration is all the time. There is that right? It's a very common what I would call misconception, but you're not technically wrong. I actually complain about this a lot. Multiple blog posts I have on it on my blog, as well as in my book. Data migration is not a one-time job. It's a one-time run to production, which is very different than a one-time run because I still have to do a QA run and I still have to do a UAT run. And what that means is that I now should codify that. I should write that in code. I'll get back to that in a second. So the difference between a data migration and integration is a migration. I would consider a subcategory of an integration. They're both moving data from one point to another. An integration is something that would happen on an ongoing basis. So it's not simply take the data and then you switch ownership of the system, which a migration is, right? I'm taking data out of some legacy system. I'm going to move it to a new
[04:20] place. The new place will then maintain ownership. Whereas in an integration, the legacy system is going to, or the integrated, or the master system would maintain ownership of the data and then continue to update the target system. Where again, with the migration, we're going to actually swap ownership. So one of the reasons I like to talk about the differences is because the thought process, and this is one of the reasons why I hate people calling it a one-time run. It's not just the nuance that yes, I have to test and yes, I have to do QA. If that because that mindset allows people to think that they can now be lax on their standards and attempt to do things manually. So what'll happen is I'll do a data migration wholly manual. I will test it. Then I will do it wholly manual again when I go to production. And what happens is I'm testing it. Client is reporting or my user base is reporting defects. I'm not fixing the data migration. I'm fixing the data that was migrated. So when I do the production run, I'm now doing a different process than I tested. So often, if there are lots of defects, they do the production run and they find the defects that were reported and fixed because it's a manual human process that's not. Automated in a way, right? Computers don't forget and make mistakes, right? They run the exact same code. Do you see a lot of customers are still doing the manual migration, which like maybe consume a lot of time, couple of days even? You see it quite a lot.
[05:50] It's very, very, very, very common. I wouldn't say that they necessarily consume a lot of days. I think the vast majority of these are small migrations. The CRM space is still fairly young, so often you're migrating from people who don't have CRM, right? So they might just be say, oh, I get my my accounts in there from my. You know my accounting system. I just need to create my companies or my contacts from Outlook. So they're very very small migrations. Where if you do something quick and dirty, it's not a tremendous amount of harm to it, or there's not a tremendous amount of damage you can do. But if you're migrating from, you know, let's say. A Microsoft Dynamics or an Infor CRM, SalesLogics or Sugar CRM, or SAP. That manual process simply not going to cut it if you come from a sophisticated environment that exists. So, does it mean? If I start to do a data migration project, I should be armed with some data skills, which makes maybe me more comfortable to run some automated process to migrate the data instead of do everything point and click and then do manual ways. Yes, absolutely. So the data skills are needed more so for the transformations. The movement is fairly straightforward, but you do want to automate it end to end, where it's very similar to coding a batch process integration, where you can run them run the migration twice, and
[07:20] you don't have to necessarily wipe out the data. So I put together in my book. I put together six attributes of a good data migration, and because a migration is a subcategory of an integration, they're basically the same six attributes that apply to an integration. Just to quickly run through them, it's well planned. I mean, you have to have a plan. You can't just decide. You know, we're going live on Friday. Email me your data, and I'll just load it in. And that's the first time they're seeing it. That's also very common. They get the data the week they're going live instead of starting early and doing you know serious data analysis on it. The second one is automated, right? You don't want to rely on human processes. That basically will invalidate your UAT or your QA because you don't know if they did those same processes again. It also makes your life easier because that won't be a hectic weekend. It's generally okay. Let me press a couple of buttons and then. I watch it as opposed to you know being up all night running migration procedures for a large migration. If I'm using data loader, is that automated or is that manual? The data loader can be automated. It has a command line interface. The Apex data loader does have a lot of people don't know that it's not a wonderful tool. And I have written fully automated data migrations using the data loader. So the other part of it is that it's written in Java, and if you're using the command line, you're able to connect the data loader directly to a database engine. It does not have to use CSVs. It's not a horrible tool. The reason I don't like it is it doesn't
[08:50] have even the automation doesn't have any data transformation capabilities. So I would have to rely on something else to do the data transformation. So it's essentially just a data pump. So I can automate the data pumps with the mappings, but I would need to leverage something else to do the the ETL tool. Right. Exactly. The transformation part of it, yeah, and potentially the extraction of it, yeah. So getting back to the attributes, well planned, automated, needs to be controlled. What that means is I need to be able to control the data that's going in and out on the migration. So and it should be able to be easily controlled. So if I if I want to say I only want to migrate the accounts that belong to a particular individual, I should be able to migrate all of his accounts, all of the contacts related to the accounts, all the activities related to all of those contacts and accounts, the opportunities related owned by that person. Right, and all of the other data related to just those accounts, right? That should be an easy way to control the data. That had lots of benefits. If I want to do a push sandbox, where I might not have the storage space. To do a whole migration, or if you're a developer, and you probably should be a developer doing this kind of work, it allows for rapid test, fix, fix your code, rerun. Cycles that developers love, right? As opposed to, okay, I made a small change to my code. Wait four hours and then check it again. Like this, it allows you to do very targeted tests that run quickly. So, control. Then it needs to be testable. So I need a way to test this,
[10:20] and that's a whole topic in and of itself. It needs to be repairable as well. So I need a way. I need my. I can't assume that once I do my data migration, I can't fix the data. That's not difficult to do. Essentially, have your external IDs. You can tie the data back. Your migration is using upserts if possible. But it should run in a way that the data can be patched, and then the last one is reversible. You should be able to back out of that data migration if you have to. So identify that the records that were loaded and erase those, and then potentially, if records were updated that existed, reverse those back to what they were. So these are the six attributes. Do you think a good migration project should have? Correct. The only difference between the six attributes when it comes to an integration is the repairable one, where repairable has to be. I don't say has to be, but it really should be self-repairable. So, if the job fails, you should simply rerun the job. And it fixes it. I shouldn't have to. The job failed. I have to go in, clean up staging tables, change settings. Then rerun it. It should simply be the next time it runs, it fixes the data. If you're doing like incremental type loads, for example, often what happens is the jobs have to run in order, and things like that, right? Because they're updates. And if I miss an update, it might, right? It might be preface the next update needed the first update. So again, you can't have it like oh, I failed the job, you missed a couple of records, and now
[11:51] you have to manually back out all of the updates that. Happened because it didn't process an order. You want the job to be easily maintained. But if that's the case, so if you miss some records, then you have to rerun from the beginning. Then that just means your design. Is flawed. Am I right? So you have to improve the design of the data migration process. So this we're talking about an integration, not not a migration. So I'm talking about every night I'm going to get an incremental load, and because they're increments, the updates have to happen in order, right? Think of it like a transaction lock or your bank balances, right? I can't have deposits and withdrawals out of order. So the things have to potentially happen in order, and if you have other processes kicking off on those things, right, it becomes even more important. So now again, let's say every evening data go you know system kicks off pulls out data and then processes it and then you know one day that fails and then the next you don't catch it till the next day and then the next job runs but we there's a record loss because you know either it pushed and it didn't know that it had to repush it or whatever so those controls need to be in place and again that whole control process. Should be built into the software. It shouldn't be something that someone has to get an alert failure and then go in and you know and intervene. I mean, it sounds obvious, truthfully, but you'd be surprised how many systems are not designed to handle errors in a in a sophisticated way. That's really good
[13:21] tip. I haven't had the chance to do too much sophisticated integrations. But yeah, that's like a huge benefit if we can, you know, retry it whenever we want, and then there's no side effect. Hundred and definitely, that's that's a huge benefit. So, what kind of like integration patterns does your book talk about? I would assume since you have done so many, there must be some like good practices and the differences between the good practices and when to use this, when to use that. So, the way the book is structured is, I spent the early chapters. The first two chapters. The first chapter is really talking about traditional databases and just database theory. It's kind of like bringing somebody who's only lived in the Salesforce world doesn't understand traditional data design. Kind of just bringing them up to speed. In some of the thinking, and then I'll take that the next chapter. I talk about how Salesforce is architected on their backend, how their data manages, and how it's different from traditional, and why it's different. And that becomes really, really important to understanding. The impact of why you're building, you know, your data model certain ways, and you know why Salesforce uses, you know, pick lists and multi-select pick lists instead of reference tables and all of that kind of stuff. How it does indexing a little bit. Then I kind of go into again a little bit deeper. The next chapter, like all the various data types and how to connect to data, and then I spend a couple of chapters
[14:51] straight on best practices. Right, does not code. It's going through these six attributes, and then a layer deeper of like forty or fifty, forty exactly. I think best practices, and I tie each of these best practices back. To those tributes, and then I go into data migrations, and I actually walk you through an entire data migration, like a really, really complex one, literally step by step. It's probably the hardest chapter in the book to absorb. And then, yeah, example to walk exactly. Yeah, one of the things I hated when I would buy tech books or read blog articles, like they'll they'll often tell you something like it's so simple, just do this, this is, but then it doesn't really cover the full scope. So I wanted people to know what they're getting into because every one of these objects has an edge case. Every one of them. If I'm loading content, there's a weird data model there. If I'm loading activities and right the children under there, there's a weird data model. How we inherit security changes how I'm going to do things. Then I have some some objects I can't put external IDs on, and I have to change my model there and figure out how am I going to do my my reversing? How am I going to do my testability if I don't have an external ID on the record? So there's a lot of that kind of stuff. And then I go into I take that's the fundamentals, right? Because again, a migration is just a subset of integrations. I then go into synchronization patterns. So these are batch process synchronization. So I need to keep two data sets in sync, and then so I start off with a really really simple pattern of
[16:21] wipe out all the data and load it back in. Your data's in sync, right? Really really easy, and then I continually. Get more complex on that. Discussing the trade offs in terms of performance, it's really the performance. But in terms of also not having to do do a data wipe. So for example, I don't want to wipe out the data. So let's do just absurd everything. But now I have an issue. How do I handle deletions? So I got to add in a layer of deleting missing records. So delete records that are in the target but not in the source, then upsert everything. Then I'll talk about time-based increments. Then I'll talk about what I call a differential. Or compare the data sets and detect differences, but again, all of this applies to batch processes. The book is completely tool agnostic, so all of these patterns—it doesn't matter. What tool you're doing? Assuming it has like basic capabilities, and then I'll go into real time integrations. And real time integrations, in a lot of ways, is easier than a batch integration because I'm dealing with one record essentially. I just have to make sure that I understand the triggering mechanism, and then you know talk a lot about the various patterns that can work within Salesforce in terms of the mechanisms. Are we going to do point to point? Are we going to do middleware? Go into a little bit about the difference between an application integration and a data integration. Where a data integration, I'm just pushing data, but an application integration,
[17:52] I might be triggering a process and then right charge this credit card, give me back the response codes, or I might surface the UI if I'm embedding UI like using Canvas. Or an iframe, so we talk, you know, a lot about the various different methods to integrate with other systems, either at the application level or straight, you know, at the data level. And we can go into some of those if you want to. Yeah. So you basically quickly went through the whole. A checklist of the book, what things we have gone through, and the reason because I can see each point one after another. There's like a a logic link in between. You started from a simple one and the difference between Salesforce and other traditional systems. Then how the migration, the migration happens. What's the best practices and the walkthrough. You know, a good example. So there's a lot of things I think you have covered. Definitely, it's going to be a great book. I have. Scanned through some chapters, but I highly recommend to the listeners who want to do, who has the need in the in the job to do the Salesforce innovation. It's definitely a really really good. I just have one thing. You mentioned at the early beginnings the difference between the Salesforce database and the traditional database. What is like if you grief me? What is really the differences? So a relational database is based on this guy named Edgar Codd. Everybody calls him Edgar J
[19:22] Codd because his middle initial is J. I don't know why. Maybe it's just because he's old enough and it's almost a historical record now. So I think it was back in the '60s or the '50s, and he designed the theory behind relational databases. And essentially, you structure your data where the data model itself enforces your data integrity. That means you essentially have IDs and you have your joins, and that's why it's called a relational database. Now Salesforce also had IDs and it joins objects based on those IDs. So people tend to think of it as a relational database, but it's really, really not because you violate so many of your rules. Of your what I would call not I would what's called normalization rules. So there's essentially five forms of normalization. It goes through first normal form, second normal form, and Edgar Codd put together the definitions of each of those. And generally, when somebody builds a database, they get to the third normal form. They don't really go more than that. That tends to be the standard now. And I'm not going to go into the rules. On the off the top of my head at the moment, but essentially is you're not gonna you're not allowed to duplicate data. That's why I'm linking by IDs. So if I need to change, so for example, right if I have a company table and I have an industry type code, and then I have an industry table with the names as opposed to a pick list. Now, let's say I wanted to add a score to the industry. So I want to rate industry computer industry as ten, and and finance as a six for whatever reason. If I have an ID, all I got to do is update my child table that has
[20:52] the industry IDs. Add a column and put the rating. And guess what? All my data is perfect. In Salesforce, that doesn't happen. You end up using a picklist, and then picklist can't have an additional attribute to it. You would have to then split it out or do some other kind of math. And then the other part of it is you can't. Salesforce only allows you to like relate three levels down naturally, or you can only put a related list one right one related list. You need the IDs on all of the children. And then you end up writing triggers and workflows to keep things in sync. It's very, very common. Is oh, I make a change here, write it to this other object. If you had a proper relational model, you would never have to do that. And not only wouldn't you have to do that. The data model itself, without writing any code, enforces the integrity that things never get out of sync. And this is not to say that Salesforce is is designing things bad. What it's saying is that Salesforce is trading the integrity enforcement for read speed. So if you think about it, if you if you go back to the example of the child industry table, right? So, if I wanted to say, okay, let me update all of the computer industries to say that it's a nine. I just update the industry record. It's one record. I write one field. I'm done. Every single account is updated because they're the join. It's a single write, so it's very fast write speed. But if I need to now get, I need to get every account record with the industry values. I got to do a join. Whereas in Salesforce, it would force you to write code that okay, if I update that child,
[22:22] go back and update the account. So what happened is it's slower write speed because I have to go update all the accounts. But now when I do a read, it's faster because I don't have to do a join. So by writing code, I'm basically trading read speed for write speed. You could also trade hard disk space for speed. There's lots of these kind of trade offs that you can do. Again, this stuff is very, very typical in the enterprise space when you're designing enterprise systems. Big data is almost completely focused on that, right? Where I'm storing objects instead of, and then if I need to update. A record. I got to update a lot of data everywhere that potential field can be referenced. The data is duplicated all over the place. But again, it's not that this is bad. It's just that there's a trade off that we're understanding and recognizing that we're going to trade off our read speed for our write speed, and that's exactly what Salesforce started pick lists. It's exactly what Salesforce does with multi-select picklist, which is a gross violation of you know relational database norms. And it's exactly what it does by all the limitations it puts on SOQL, which is why SOQL is a much weaker language than SQL, and SQL is the standard database querying language, right? Because they don't want you to abuse the CPU, and they're going to say that okay, if you need this complex join. You have to then push it over to the right side of things, meaning the not right, the correct. Where you have to write the data to enable it. To run these kind of reports that you want, so they design the system to put these governor policies
[23:52] in place, so that you have to design your system in a way that you don't abuse their CPU, and that you that forces you to trade off. Trade off meaning a slower time to write data than to take to read the data and to do your reporting. And again, once you understand this in a good way, it really really helps you to design your systems and to design even your Salesforce. You know, data model better, and and all truthfully, when you're building your integrations too. Yeah, I think including myself, a lot of listeners can grab the the high level picture, the big ideas what you mentioned. So in Salesforce, some data columns tend to be copied between different tables. That's the reason that you don't need to go to another table to retrieve additional data when you need it to. So that makes the cycle faster. But on the other side is that it consumes more space, and each time when you write into one place, one slot, you have to copy the changes to all the other tables in the same places. Right, exactly. So it's not just the disk space, though it's true what you're saying. It's disk space and the type to update, the time it takes to update a record, because a trigger has to run. Yeah, it's one of the reasons integrating with Salesforce can be painful, because you end you end up often on these locking errors. But if I figured out the difference, is there something you mentioned it can help me improve my data design?
[25:23] Is that really the case? Because Salesforce is already designed, and the traditional database has its own design. What you mean is, I can what can I do in between as a person? I can give you another example. I once had a client. They needed to store. They were working with pharmacies, like their locations. So they had like every pharmacy in the country, maybe a million of them. It's a lot of records in Salesforce, and Salesforce storage is not cheap. And they wanted to store their hours of operations. Including their time, their open and close for lunch in Salesforce. So, so what are they doing? Like, if you think about it, they're open five, seven days a week, each store potentially, and you have a million records. If I'm going to create a record for each day, open, close, and lunch. It's another seven million records in Salesforce. It's a lot, and they didn't want to pay for that storage, honestly. And it's not just financials; like it's also, you know, it's also again a lot of storage. So, like I had a conversation with them, like, okay, what do you want to do with this data? Do they need a report on it? Like, are you going to really run a report like who's open on Tuesday at five o'clock? And their answer was no. We just need to see it on the record. So, like once you understand these techniques, like okay, not a problem. I'll build you a little table. And I put it into a rich text field, and it looks nice. Displays right on the screen, and it's exactly the same thing, right? I'm denormalizing the data and putting it into a single field. It looks like a grid on the screen, and guess what? No storage. It's all on the same record, so there there are kind of things like this that you can do. One last thing,
[26:53] I still want you to tell me is that you have a really good LinkedIn post. It's talking about the like locking like errors in Salesforce. Am I right? So it's like a record is locked. Yeah. So often, when you're pushing a lot of data, you end up with locking issues. And ninety five percent of that, it's self imposed. I think what makes his posts so popular is that. Not so much that it tells you how to avoid it, but it really kind of dives into how Salesforce works underneath the hood. So essentially, if you update a record in Salesforce, a master detail, it locks the parent record, even if there's no cross object formulas, still locks the parent record. Now it's interesting because again, in relational database, a cross object formula is also Under the hood, it's doing it right. That's why it locks the record. And again, that's a violation of the normalization rules. But they have code again that forces and maintains your data integrity. So even if there are no, there are no cross object form, it still locks the parent field. And what happens is if I'm pushing a batch of 200 records, and there's 200 contacts in there, and let's say three of those contacts apply to the same account, it's only going to lock the account once. So if I'm now pushing serial batches. And these three contacts are in three separate batches. That's three locks, and not only they're three locks because they're
[28:23] all going at the same time. Guess what? You have a lock collision because they're both trying to lock the record at the same time, or all three of them are trying trying to lock the record at the same time. One might win, none might get it. Most likely, it's just going to retry. Salesforce will retry ten times. And then eventually it will go through, but the truth be told, locking is a very expensive operation in terms of time and CPU. The retrys are expensive. So it just ends up going very slow, and then people like, "Why is my load going so slow?" But they don't realize is that Salesforce under hood is, "Let me get the lock. I can't get the lock. Retry. Let me get the lock. Can't get the retry ten times, and then you have three records. So guess what? That thirty times." Potentially, and then it gives up and fails, on one of them. So, like a really simple thing, if you're doing bulk data loading, is if you sort. Your records by the account ID, the contact. Then you're gonna basically say, oh, they'll all be in the same batch. Even if I do ten batches, because now I'm limiting the possibility of contacts belonging to the same account spread across multiple batches. So simple little things like ordering your data can make a big difference. And you would only come to that conclusion if you understood how it worked, or you did a lot of research. The other thing is again lookups. Lookups, if they're not going to restrict you from deleting, like the lookups have settings. So if I create a lookup, I can say you can't delete the parent, or if I clear out the ID,
[29:53] allow it to be null. Not required. So if you if you change some of those settings, it also will not lock the parent. So a way, though, to configure those relationships so that they don't cascade locking, and that will also speed up your loads. Yeah, so it it goes through a few of these kind. It it explains the underlying procedures, kind of like kind of like what I did, a little bit more in depth. And then it talks about some of these ten techniques: ordering your data, setting your joins properly, and then the last one would be strategically turning off your code workflows, triggers. So that they don't execute that one is a bit of a tricky one. Again, if you read online, I think I was complaining about them before. There's so much bad advice online when it comes to data migrations, not so much with integrations for whatever reason, and I think that's because. Integrations tend to be developed by more developer types than admin types. So, but the idea with turning off the code is, one, you have to know what the code is doing. Like, you can't assume that that code is just okay for it to not run on the updates. So, if you turn it off, then just make sure that you write a process that will do whatever that code is supposed to do. So, if you have a rollup, write like a like not a rollup summary, but if you had a trigger that calculated a rollup. And then put that on another field. So that's fine. Load your data, then do the math, then update that field, then turn the trigger back on. Right, and that can make a huge, huge, huge change in your
[31:24] in your migration. Unfortunately, that's generally not an option for an integration that you're gonna. Like on a nightly basis, turn off. But if you had to, you probably could. Honestly. So I want to step back a little bit, talking about the locking because it was really interesting. I just wonder how did you find out? These things under the hood running in Salesforce. How did you even start to thinking about that? Was because you see the integration runs really slow and they try to dig into that. Why was that the the motive? So I think I found a white paper or like a or video from Salesforce once on performance tuning. I mean, I was doing research on the subject. On all right, how do I performance tune my my bulk loads? And then you kind of just picked up on this stuff, but I think that video that I saw really, really explained the locking mechanism in layman's terms. But because I have a strong data background, I fully understood. What they were saying, with regard to the other part about the denormalization, that is just standard stuff. If you're outside, if you're like a decent data analyst or database person, this is the kind of stuff you're doing on your normal basis. I have a report I need to run it every night. It's really really slow. So, what am I going to do? I'm going to just try to update it in real time. Throughout the day, right as changes come in, or I'll again denormalize my data because
[32:54] I have something that needs to run fast. So this is just—they're just standard techniques that you see Salesforce doing it when you're looking at how it works. Got it. Thanks, David. This is all the things I want to talk to you. And again, thanks to you that I I read your book, and you know. I didn't really go into the details, but you really made me intrigued. I want to go through the book in details now. You know, yeah, you should, you should. It's really wonderful. And the truth is, like I know you've read part of it. It's not a, it's not a difficult read. It's not super technical. I tried to keep it light. I tried to keep it also an enjoyable read. You know, people, you know, a little bit on the humorous side. And I do have a a lot, a lot of footnotes in the book. So everything that I'm telling you, I link back to like the source of that information, where you can get a lot more. So I'm sure if you go to that chapter on performance tuning, you'll find a link, maybe not to that video, but to at least a white paper from Salesforce that explains the interlocking stuff. Excellent. Thanks again, David. It's great chatting with you. See you next time. Hi. Thank you. Yeah. Always.
[34:12] Hi, I'm constantly looking for good guests. If you have any guest recommendation, please reach me out. I'll make sure they're joining to the show to share their knowledge. Otherwise, thanks for listening to the show. I'll see you next Thursday.