App Performance (>10k row apps)

It would be great if all performance tips would be put in 1 place for everyone to share. I’m sure some tips might change with time as Glide changes. I’l post a few questions and would love support if anyone can confirm or give a better suggestion or even rank which ones are the best for performance.

Row Owners

  • can they really be used to speed up an app for some of its users?

Glide Tables

  • Reduce the edit count compared to a Google Sheets source.
  • Do they really speed up the app, some can argue that time to fetch the data similar to GS.

Computed Columns

  • is there any ranking as to which types of computed columns take longer than others or which to avoid in big apps?
  • Does reducing computed columns drastically improve the performance of an app?
  • Single Self Relations are they really a bad practice?

Images

  • Cloudinary Fetch / QuickChart should we limit them to the least number of columns. so instead of creating 4 image options and an if statement to select 1. We create computed columns with if statements and one fetch call depending on the values of the computed columns.

any other important advise for app performance

2 Likes

I’d say yes, it can speed things up for the end user. Applying Row owners means that substantially less data will be downloaded to a user’s device. Less data means less calculations that have to be performed by the end user’s device. All computed columns (anything that is not a basic column) are computed by the end user.

In my opinion, Glide Tables do not speed things up compared to GS. Even if you use a GS, Glide is still storing a duplicate of that data essentially in a glide table. So from an end users view, they won’t know the difference if you use glide tables or google sheets. Data is served from glide servers regardless. The only slowness with google sheets will happen if you rely on certain calculations that happen in the google sheet instead of within glide.

Generally computed columns are pretty fast. I think where you will start to see issues is if you have computed columns that rely on all relations to build first, and or relations that rely on all computed columns to run first.
So if you have 10k rows relying on a relation to 10k rows to calculate something, all of a sudden you have 100 million loops of calculations that are running on each and every users device (maybe a bit of an exaggeration, but you get the idea)

If there is less to calculate, then there is less code to run through to calculate something. I don’t know if I would say “drastically”, unless you have some calculations that are massively intense.

Probably not, but those those single relations may or may not return a value until the rest of the table is calculated. Hard to say on that one.

Glide does not serve up images along with the data. They only serve up the url. So no, I don’t see an advantage placing a url in separate columns compared to directly in the IF column, other than a little extra text for the url. The app (which runs on top of a browser engine) will not download and render an image until the data is downloaded, computed, and displayed on the screen. Images are only downloaded when needed. It’s really the browser that takes that url, downloads the image, and caches it on the user’s device. If an image is not displayed in any way, then the image is not even downloaded until it’s needed. Take YouTube for example. Only the page code is sent to the browser. YouTube doesn’t send you the entire video file, it just tells you where to find it in their storage and combined with their page code, it knows which video to stream to you.

5 Likes

Theoretically yes, they do help because your users are downloading less data, but if you apply a lot of columns as row owners it will be hell to load initially, since Glide needs time to compute what they should send to the user’s device.

I have seen apps with a lot of computed columns suffering performance-wise, so I would say yes.

If you’re referring to relations to the same table, I have seen that mentioned a lot in this forum that it is a bad practice.

I’m not sure if it matters, since what matters, as I understand, is when you actually display that image in the app. The device downloads that image and caches it, from that point onwards you should be good with that specific image.

2 Likes

@ThinhDinh, @Jeff_Hager
Thank you for feedback, I tried to sum things in the last reply if you don’t mind, in case anyone wants to quickly read or add to this. I guess for performance is a major issue for anyone trying to seriously rely on a Glide tech solution

1. Row Owners

  • Appears to be a good practice for speeding up apps.
  • Less data downloaded to a users device
  • Less computed column calculations done at the end user device.
  • Make sure not too many columns applied as row owners since Glide needs time to compute what they should send to a users device. ?? (Min of 3-5 probably needed, to give multiple people access to this row. as you cannot use the Google Sheet method of RowOwner1, RowOwner2 etc…)
  • Seems to be The Top Rank Step to improve app performance according to this conversation?

2. Computed Columns

  • Computed columns should be fast.
  • You start to see issues if you have computed columns that rely on all relations to build first, and or relations that rely on all computed columns to run first.
  • Apps with a lot of computed columns appear to suffer performance-wise.
  • reducing computed columns does improve performance, these computations are done on the user side.
  • Relations to the same table appear to be a bad practice? (Negotiable) I guess most people do this for design purposes, a card of the row, etc…

3. Glide Tables

  • Glide Tables do not speed things up compared to GS.
  • Glide is still storing a duplicate of that data essentially in a glide table.
  • Performance can be affected only when calculations happen in google sheet instead of Glide.
  • Seem like Glide Tables is a no question for the future of using Glide if you want to make a lot of edits on the data you store. Google Sheets edits are very limited and costly on Glide ??

4. Images

  • Images are not downloaded the same way data is when loading the app.
  • Only when an image appears on the screen it is downloaded.
  • Having multiple image columns or computed columns (which you don’t all use) isn’t a significant impact on app performance.
2 Likes

This is a nice summary, this is great for everyone. There are some points I would word differently, but it’s your post so it’s up to you if you want to edit, if my suggestions even make sense:

Fewer rows, therefore less data is downloaded to a user’s device, which might improve app performance.

Fewer rows, therefore less computations of computed columns, which might improve app performance.

  • Basic columns: Glide Tables does not speed things up compared to GS. Because Glide is storing a duplicate of basic data from GS in Glide Tables.
  • Computed columns: Computations on basic data in Glide Tables happen on the user’s device, computations in GS (formulas) happen in GS and these results need extra time to sync with Glide (GS–>Glide) and then again with the user’s device (Glide–>device). So in the case of computed data, it is probably better for performance (time delay) and cost (see syncs in plans) to perform computations in Glide Tables rather than GS. In other words, avoid formulas in GS and use computed columns in Glide Tables instead. Here, “GS” can be replaced by “any external data source” or “any data source other than Glide Tables” (Eg. Excel/Airtable).
5 Likes

@nathanaelb yes for sure i’l update. want to reach the best possible performance advice we can give and your terms make it clearer. I hope i summarized your points correctly

1. Row Owners
Advice: Seems to be a good practice for performance and app speed.

  • Fewer rows hence less data downloaded to a users device.
  • Fewer rows hence less computed column calculations done at the end user device.
  • Make sure not too many columns applied as row owners since Glide needs time to compute what they should send to a users device. ?? (Min of 3-5 probably needed, to give multiple people access to this row. as you cannot use the Google Sheet method of RowOwner1, RowOwner2 etc…)
  • Seems to be The Top Rank Step to improve app performance according to this conversation?

2. Computed Columns
Advice: Reduce

  • Computed columns should be fast.
  • You start to see issues if you have computed columns that rely on all relations to build first, and or relations that rely on all computed columns to run first.
  • Apps with a lot of computed columns appear to suffer performance-wise.
  • reducing computed columns does improve performance, these computations are done on the user side.
  • Relations to the same table appear to be a bad practice? (Negotiable) I guess most people do this for design purposes, a card of the row, etc…

3. Glide Tables
Advice: Switch big tables into Glide Tables.

  • In general the use of Glide Tables does not speed things up compared to the normal use of GS.
  • Basic Columns: No difference in speed, Glide is storing a duplicate of basic column data in glide tables.
  • Computed Columns: Always try to use glide computed columns for computations rather than Google Sheet formulas which can allow time delay and slow down performance.

Notes:

  • Syncing with google sheets is limited in accordance with Glide plans while editing data in glide tables is currently unlimited??
  • Seem like Glide Tables is definitely the best option for the future of using Glide especially if you have big tables and require a lot of edits on the data you store.

4. Images
Advice: Don’t worry too much about image columns.

  • Images are not downloaded the same way data is when loading the app.
  • Only when an image appears on the screen it is downloaded.
  • Having multiple image columns or computed columns (which you don’t all use) isn’t a significant impact on app performance.
5 Likes

Thank you for this! –appreciate you trying to codify all of this info. I’ve read varying theories … My own app has been hindered by performance issues and i’m about to start a two week sprint in addressing problems.

Really wish the Glide Team would release a best practices post (like this) and make it easier to test/root out performance issues.

1 Like

For those wonderings what a “Single Self Relations” is and why it is good and/or bad. Here is good thread/article I found:

5 Likes

Great you brought it up. I think we have to add more about this point and in general relationships in this thread.

Relationships

  • Relationships with different tables
    Using a multiple relationship to prepare a list of related rows from a different table in the glide editor rather than displaying the entire list in layout and using filtering capabilities Glide offers and adding a lot of filtering rules. Does this really decrease performance way more than the filtering or exactly the same?
  • Extra Relationship Columns
    I think many prefer to use extra relationship columns. Lets say an Orders Table. You want to have a relation column for related Item rows. A relation column for related Today Item Rows. which is exactly the same as the first just adding a few filters, or a column for Sale Items in this order etc…

A big question is how does Glide deal with relationships… i assume they must have though about this with performance on the top of their priority… hence when you create a relationship column, you cannot use values of related rows directly in the layout, to use related row value you have to lookup store it in a new column and then use it. So i guess a relationship doesn’t download all data of the related row maybe just returns the row id initially and so the decrease in app speed & performance isn’t that huge?? Just brainstorming here

There is a third option.
Which is to use the entire table in an inline list, and then build logic within the table such that a single filter condition can be applied to the inline list. It’s possible to build very complex filtering using this method, and is my preferred approach.

2 Likes

Yes i use this a lot. I try to never filter by multiple conditions, instead the logic is created in GDE and then one filter is used if True show the row.
Can we confirm though performance wise for apps with over 10k rows, its way better to do this than to actually make a relationship column and display that column in the layout?

My points of view:

  • can they really be used to speed up an app for some of its users?

Absolutely!.. Row Owners is a kind of filter and will help you to load a more specific data associated to a user, your APP will be lighter.
E.g., why do we have to load 10k rows associated to all customers’ sales when a normal user will verify or use only 3-5 rows of those 10k rows?

  • Reduce the edit count compared to a Google Sheets source

I’d say yes. There are fewer syncs from external sources using GT instead. Also, Glide will love you due to there will be less cost and payments to Google, Microsoft, etc

Working with GT is faster than with GS and you will see the difference the more data your GS has

  • is there any ranking as to which types of computed columns take longer than others or which to avoid in big apps?

I don’t think there is a list of good/bad computed columns, the problem is how you use them and how many you have created to get a result. Sometimes, there are clever solutions/ideas and you only create 2-3 columns to get what you want but sometimes, the no-code tool isn’t enough and smart and makes you to create 5-6 columns to have a simple result (true/false).
These additional columns will cause performance issues when you data exceeds 1k-2k rows probably.
Here an example about it…

  • Single Self Relations are they really a bad practice?

I’d say yes again. I have seen it several times by accident testing things. It’s similar to using VLOOKUP() formula in the same GS searching cells/values among thousands of rows.
If you have too many rows, the sheet gets heavy and crashes sometimes when a row is added/removed or even when other columns have new values

I use a self-referencing relationship as plan B and if my table is small.

Saludos!

3 Likes

@gvalero, thank you for the feedback, i’l try to sum up the comments as I did above and merge it with everyone’s opinion.

Yes it seems that we all agree that Row Owners are the top priority to improve performance for most app users. Though some roles might still have to access all app rows so its important to find performance parameters to build a better app for them (ex. admins)

I don’t know if I can offer up an opinion if Relations or Filters are faster than the other. Most of what I’ve learned has been a lot of trial and error to make my own app run faster. I don’t think I’ve run across a scenario where I could directly compare the use of relations to filters.

Many times when I use relations though, they have a deeper purpose, such as needing associated Lookup columns, or Rollup columns to create summary totals. I often do not have a relation that stands alone without other column types that use that relation. For that reason, I’m stuck with using a relation over a filter.

If I were to honestly make a guess though, it’s probably not that much different. Like you said, a relation is more of a pointer to related rows. It’s not really transferring or moving any data.

I think the biggest determining factor for speed is how or when a table is accessed for the first time by a user. I think what happens is that when a table is accessed or needed in any capacity for the first time, then that’s when all calculations and computations are initially perform within that table. That could mean that you are accessing the table directly, or the table is being used through a relation or some other means. Once a table has been accessed and processed the first time, any subsequent calculations only happen on rows that have had data changed, and of course, any related rows that may be referred from, or referred to, are affected as well. I’ll use my app as an example. I have a table with 8k to 9k rows. There are a fair amount of calculations, and relations that link to and from other tables. I have made several improvements over the years, but I still have speed issues. But primarily, the tab is only slow to load the first time after the app is opened. If I leave the tab for another tab and come back, things open much quicker. My theory is that the large initial spin through the calculations is now done, so things become quicker. For my case, it’s a horrid situation where I have relations linking one table to another, and that other table has relations that link back, and there are other relations to other tables involved. It’s borderline an iterative or circular loop situation, but not quite.

I will also mention that I still have some logic contained in the google sheet. I have a weird situation where I have a table of lessons taught to students, a table of billing cycles (billing start and end dates) for the coach, and a hybrid query sheet that summarizes lessons, per student, per billing cycle, per coach. Lessons can be recorded before or after a billing cycle has been entered for a coach (this coach does not bill students on a normal predictable schedule). So I have to magically connect existing lessons (child rows), to a new billing cycle (parent row). I can’t use a billing cycle Row ID and attach it a Lesson when it’s recorded. I have to do that behind the scenes in the sheet. I did come up with an elaborate way to accomplish it within glide, but the number of additional relations and computed columns made the app horribly slow. Keep in mind it had to calculate this stuff 8000 times. I found it much more effective to just do what I did in the google sheet instead. It allowed me to create more efficient relations in glide as the results didn’t need to be immediately shown in the app.

I still have other things I want to try to make my app better, but like I said, it’s just a lot of trial and error and I think it can be very specific to your individual use case. Glide is quite powerful and can do a lot, but it’s good to have an understanding of everything it has to do behind the scenes…and especially at the mercy of the processing power of an end users device.

Glide is working to migrate apps to the same computation model that was developed for pages, so I do forsee performance improvements in the future. I don’t really know anything about the old or new computation model or how they work, but I do believe they are working to make things run faster in the future and more efficiently in the future.

5 Likes

My demo applied to Multi Filters is my best effort to test and know which method is better: filters or relations

Unfortunately, I didn’t have more data (rows) to test it and see its perfomance working with 3k-5k registers :face_with_raised_eyebrow:

1 Like

Yeah, I was going to make this point as well. I think I’ve started to avoid relations as the source of Inline Lists, but still (of course) use them for other purposes. Part of this is probably because there was a really frustrating bug a while back where inline lists based on dynamic relations wouldn’t always update correctly when data changed. So I started moving away from relations for inline lists and discovered that for most cases I didn’t really need them.

Actually, you can even avoid relations for summary rollups with a bit of creative use of if-then-else columns. But that can get a bit complex, so at some point the law of diminishing returns starts to kick in.

Absolutely agree with this, and my own experience bears it out. I use a lot of HTML/CSS tables in some of my apps. In the largest of these (an app with over 30k rows), every time I fire it up and navigate to a screen with a HTML table, I initially see a bunch of bare <table> tags whilst the table data is being calculated. But once it’s done, I can navigate away from that screen and back again and the table renders instantly.

3 Likes

Everyone commenting, or maybe even reading this thread, is an advanced user. We manage to achieve performance enhancements, but also unfortunately basic features, with what I would consider advanced techniques: filtering data in the GDE instead of in the builder and rollups come to mind. I expect this to change in the upcoming weeks/months, because this is not what Glide is about and David has made clear that 2022 is about simplifying things.

When it comes to pure app performance (and not dev “buildability”), I find what Jeff mentioned about relations being pointers with no data transfers eye opening. I had never seen it that way but it makes sense. I had always seen relations pulling data from one place to another, but maybe not.

So with those two points in mind and to come back to the topic of this thread, app performance, I’m not really convinced that relations are all that relevant to app performance.

3 Likes

Before and during to this discussion i do feel that relations aren’t a major impact on app performance. I am as well convinced that relations are an important feature for Glide that will continue to develop and hence cause even less performance issues. Will try to sum all this up in a new summary so that anyone following doesn’t have to go through all the above.

1 Like

I would say that the same could be said for all computed column types. And yeah, it is a bit of an ah-hah moment when you realise this (at least it was for me). The Glide journey is full of these little epiphanies. Understanding how User Specific Columns work was another for me, as was understanding the impact of Row Owners :slight_smile:

I’d say that they are in terms that they add to the computational load on the end user device. In most cases, that’s probably negligible.

Might be best to wait for a bit, I’m sure there will be more comments to come :wink:

2 Likes

If relations simply point, especially to data that’s already been downloaded (or being downloaded upon the first screen load), what do they compute? Or is the fact of pointing a computation?

A nice experiment would be if we took all the relation columns in all tables and did a copy-paste of the data onto the column (like what one might do in GS to remove formulas and just keep the data). I wonder if app performance would be enhanced.