Slowness is making my app unusable

I am on the Individual Plan.

As of a few weeks ago, my production app started running much more slowly. It is now at the point of being barely usable by my customers.

All heavy lifting is completed via scheduled background tasks and those run fine. But the client side continues to be very slow for any kind of action:

  • Initializing form and getting current user info takes about 20 seconds
  • Reading one value from a cookie takes 13 seconds
  • Pulling a list of values from Data Tables and putting them into a dropdown takes 18 seconds
  • Changing a few display ‘cards’ to not visible takes 19 seconds
  • Pulling a stored figure from Data Tables and displaying it takes about 30 or more seconds, often causing client timeout errors

In case it is useful, here is the start of my MainForm. This shows code usually takes between 18 and 22 seconds to execute for users who are already logged in (log-in status is persisted for 1-year).

class MainForm(MainFormTemplate):
  def __init__(self, **properties):
    
    t_pre_init = datetime.now()

    # Set Form properties and Data Bindings.
    self.init_components(**properties)
    anvil.users.login_with_form()
    
    self.user_type = anvil.server.call('get_user_type')
    
    t_post_user_type = datetime.now()
    print(f"initialize + get user info took {(t_post_user_type - t_pre_init).seconds}")

Could I be doing something wrong? Is there any way to fix this?

Thanks in advance for any advice.

Those timings seem incredibly slow.
I guess the question is - what does that server call do? I presume it’s that server call that is taking all those 20seconds

There are some posts about how to improve speed in the forum.

Suggestions to optimize performance

Typically if I have something on the client that’s taking more than 1second to complete (usually because of retrieving and manipulating data table stuff) I’ll work out ways to load the minimum necessary and turn the rest into a background task.

2 Likes

Have you tried adding a print('something') after each line of code? Keep in mind that prints on the client side are fast, while each print on the server side requires a round trip, but only when you run the app in the ide.

Have you tried to remove all the data bindings? Sometimes they trigger round trips, and sometimes they call slow functions. I sometimes put a print('function name') as the first line of each server function, so i can look at the log and detect unexpected calls.

Have you looked at the app log and noticed anything unexpected?

3 Likes

The key to tracking this down, as implied above, is measurement. Find out where the time is going. It’s often not in the obvious places.

Hi @matt, I got the same issue with my production app and I guess I know why

When more users use the app, it will slow down everything to the point that it is impossible just to load it.

Moving to the next plan will surely solve the issue. I am not too sure about the open source app. Will try and let you know

Thanks, @Tony.Nguyen. I am on the individual plan.

I’ve found significant differences in execution time based on time of day so I wonder if it has to do with number of users, or perhaps my app is being run on a shared resources and it has to do with other apps reducing their load? Usage of my app doesn’t change that much during the day since I am running kiosks that update their data 24/7.

I looked at the business plan but it seems that you have to pay $300/month just to have the opportunity to pay $100/month per extra compute unit.

Hi @matt,

My extensive stress tests find that each individual plan has certain amount of compute unit and doesn’t share it with others.

Number of users really affact the performance since each server calls reduce it significantly though it is background task.

Interacting with table is to be minimised as well.

I really don’t want to use the open source app server, but prepare all the codes for it just in case

I forgot to include the server-side code but it is something very simple that shouldn’t take long. Even pure client-side code seems bogged down.

I’m doing most of my heavy lifting via background tasks but am making a lot of calls to server functions from the client, to retrieve data stored by the background tasks, etc. Thanks for the link on how to optimize. I think the advice to reduce number of server calls might help me out.

Interesting info about the server-side print statements requiring round trips, but only when run in the IDE. I had no idea about that, and it certainly could be affecting my performance calcs.

I’m not so glad it helped :frowning:

After I ready your reply I thought about it and I realized that what I wrote earlier doesn’t make any sense. Both server and client side prints access the app log, so:

  • when running on the IDE they both require a round trip, the client for logging, the server for displaying
  • when running the production environment, the client requires the round trip to access the log, while the server doesn’t require the round trip because it doesn’t need to print on the console

So… I apologize for giving the wrong information, and kudos to the Anvil team: I made a quick test, and the prints are very fast both on the IDE and on production. Perhaps the round trips required for logging are not synchronous and each print takes at most one thousand of a second.

Obviously, printing the result of a function that triggers round trips or is otherwise slow, would not help, but, yeah, obviously.

I still stand (so far) by the other consideration on my previous post about the round trip required by the data binding.

1 Like

Are you still struggling with this? This server call

has got to be doing it. We run into this kind of thing a lot with Anvil.

If you haven’t already solved it, I would look closely at your server imports, or post your code (or a clonable link) for more info.

Note that Anvil may load all your server code on any call, so a server module that’s slow to initialize (slow imports or slow code in the global scope) may slow down other calls.

Try removing all server code, and installing a simple module that does nothing. Call that to get a baseline, including the Round Trip Time for your location. I’ll bet if you remove all server code, the time will come down to 1-2 seconds, tops. Then you can put things back half at a time to find out where the real time sink is.

1 Like

Another option: look at the server-side changes that were made just before the slowdown occurred.

In my case, it was a set of plotting routines. I had added 3 imports. By moving those imports into the functions that needed them – by importing them only when actually needed – the other server calls went noticeably faster.

In other cases, it might be a new set of database operations. In those cases, caching results in anvil.server.session might speed things up a bit.

1 Like