App Performance (>10k row apps)

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.

I think technically yes, but as I suggested it’s probably negligible in terms of impact on performance. I guess a much bigger factor would be what you subsequently do with those relations. For example, let’s say you create a relation to a table with 5k rows. And then you add a series of Lookup columns to fetch values via that relation. Then you might use the values from those lookups in a template, and then use that template to create another relation, and so on… All of this is going to create a much bigger computational load, because every calculation has to be done 5000 times.

But honestly, I think we might be making too much of this. The app I referred to earlier in this thread (the one with 30k+ rows) also has roughly 2000 computed columns, and at least 100-200 relations, with many of them being quite complex - lookups and math columns and if-then-else columns and templates - all feeding dynamic relations and constantly changing based on user interaction. And… the app works fine. So, at least in my experience, I think you need to do some pretty crazy stuff before you create any significant negative impact on app performance with computed columns.

Also, we know that in the not too distant future apps will be migrating to the NCM (New Computational Model), which can be expected to provide a bit of a performance boost.

Yeah, but as you noted earlier - relations only provide a pointer and don’t contain any actual data. So there is nothing to copy :slight_smile:
If you had a lookup based on that relation, you could probably make a static copy of that. But all that would give you is exactly that - a static copy of the data, which would be redundant and no longer in sync with the data in the source table.

2 Likes

This sums it up pretty nicely :point_up_2:

I think there’s consensus as to the importance of where the computations happen: computed columns in a GT or formulas in GS.

2 Likes

I hope i have summed up everything above and waiting for any new advice.

Glide Performance

This discusses the best practices to improve the performance of large Glide Apps with over 10k rows.

:bulb: The biggest determining factor for speed and performance is when the a table is accessed for the first time. That is when all the computations are initially performed for all downloaded rows. After that, any new calculations or delays are caused only by the rows changed.

Row Owners :trophy:

:studio_microphone: Using row owners appears to be the best step to improve app performance & speed.

:warning: Dont assign too many columns as row owners as Glide requires time to compute what to send to a users device.:thinking:

  • Row owners allow less rows and hence less data downloaded to a users device.:white_check_mark:
  • Less rows downloaded means less computed column computations done on the end users device.:white_check_mark:

Glide Tables

:studio_microphone: Switch big tables into Glide Tables.

:telescope: Synching with Google Sheets is limited in accordance with Glide plans. Seems like Glide Tables is the future for using Glide especially if you have big tables and require a lot of edits on your data.

:telescope: Use Glide Tables & Glide will :heart: you. Google Sheet costs Glide a lot of :dollar:.

  • In general the use of Glide tables does not speed things compared to the normal use of Google Sheet. Glide is storing a duplicate of all basic column data in Glide Tables. Computed columns are computed on the users device.:white_check_mark::thinking:
  • If you have a lot of data, working on Glide tables is more organized and faster than working with Google Sheets.:white_check_mark::thinking:

Computed Columns

:studio_microphone: Reduce computed columns.

:telescope: Apps with a lot of computed columns appear to suffer in performance.

  • Reducing computed columns must improve performance. These computations are done on users device.:white_check_mark:
  • Computed columns should be fast.:thinking:
  • 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 computed columns to run first. (examples …:thinking:)

:warning: Don’t replace Glide Computed Columns for computations with Google Sheet Formulas. GS formulas create time delay and slow down the app performance more.

:spiral_notepad: Glide is working to migrate apps to a new & better computation model developed for Glide Pages.

Relations

:studio_microphone: Reduce relations if possible ( Not very significant​:thinking:)

:telescope: A relation does not download all the data of related rows. It acts as a pointer to the related rows.

  • Relations to the same table are a bad practice.:thinking:
  • Using Glide filtering capabilities is better than adding a relation column to filter rows.:thinking:
  • Don’t use relations as sources of inline list. Use for deeper purposes such as needing a Lookup Column value.

Images

:studio_microphone: Dont worry too much about image columns.

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

WTF! … why not? :rofl:

To me, this saves a lot of time and works very fine.

I prefer to use a relation instead of creating many lookup columns to use them in the inline list later.

:rofl: don’t take it too personal there was supposed to be a :thinking: emoji after that
not really sure why you need lookup columns to use in the inline list?
i’m just summing up the opinions above… personally i think its very similar in performance and very organized with relations. i do use them a lot even when I don’t need them for display.

1 Like

saving app building time isn’t really the biggest concern in this thread. dealing with live apps over 10k rows, and live edits … just trying to build an understanding of whats best for app performance/speed for the users on it.

No problem my friend :muscle: , it’s just a joke

not really sure why you need lookup columns to use in the inline list?

Let us assume we are using the Details Layout (style) on a Tab called X (which points to table called X) to put an InLine List and read data belonging to another table (e.g. table Z). To do it without a relation you must create several lookup columns to retrieve values from table Z and fill Inline’s settings out and even, the Details screen associated to each item.

Too many steps, too much data to handle and too much wasted/invested time. To avoid all this, the smartest solution is create/use a relation if possible, you won’t have to create any new columns (lookup) for it.

Feliz día Rayo!

2 Likes

Off course i was joking also all is cool.

I’m not sure but i am confused with what you said, please correct me where I am wrong. I have several examples where I don’t use a relation and lookup columns are not needed.

Tab/Table X = Admin Panel
Table Z = Orders (has an if/else column isProcessed = True/False

Tab X is just a detail screen 1 row table. Inside the tab i can have an inline list from Table Z and show any value necessary without any lookup columns. I can filter it by isProcessed = True and I get all processed orders.

i could also however from the data editor in table X have a relation column to table Z that returns all isProcessed orders. and then display that in the layout.

personally i feel both are very close in performance …?

Ah ok!.. I know what you mean, sorry :innocent:

I was talking (or writing) about my case when I used to do this kind of things in my first months using Glide.

I don’t remember well if the Inline List always was able to work with a relation but in 2019-2020 I didn’t know it and used to create many lookup columns in order to work with an Inline list which pointed to another table. Suddenly, I noticed that I could work with a relation directly with an Inline list and everything improved and my life was happier. Since then I use relations with no problems and with no mercy!

Which is better in performance for working with an Inline list: a filter or a relation? I still don’t know but depending on case and complexity (I always try to avoid creating unnecessary computed columns) I can use any of them.

Saludos, feliz noche!

1 Like