Pdf Generation Memory Problem

Hi all,
Please I have an issue with generating multiple sales invoice files, slightly over 3000 for now but will grow overtime, zip and save on the system. It is set as a recurrent task (daily actually). The problem is after it generates about 1000, it gives “OSError: [Errno 12] Cannot allocate memory”. It’s hosted on AWS.

tasks.py
`

def save_all_invoices():
    all_sales_invoices = frappe.get_all("Sales Invoice", fields=["*"])
    for sales_invoice in all_sales_invoices:
        customer = frappe.get_doc('Customer', sales_invoice.customer)
        customer_email = frappe.db.get_value('Contact',{'customer':customer.name},'email_id')
        sorted_stages = utils.get_all_sorted_reminder_stages(customer.estate)
        if not sorted_stages:continue #Stages not set for company
        reminder_stage = get_stage_to_notify_customer(customer_email,sales_invoice,sorted_stages)
        if not reminder_stage:continue
        # Save each Sales Invoice 
        fm.save_sales_invoice_and_reminder_stage(sales_invoice,reminder_stage.print_format)
    fm.create_zip_file_for_all_sales_invoices()

`

file_manager.py

def save_sales_invoice_and_reminder_stage(sales_invoice,reminder_stage_name):        
    # DEBUG CODE        
    # sales_invoice = frappe.get_doc("Sales Invoice","SINV-00001")        
    # reminder_stage = frappe.get_doc("Payment Reminder Stage","2ec4b5c8af")        
    # ************
    
    customer_name = sales_invoice.customer_name
    
    customer_name = customer_name.replace("/","-")        
    year = sales_invoice.due_date.year        
    month = sales_invoice.due_date.strftime('%B')        
    company = frappe.get_doc("Company",sales_invoice.company)

    zip_file_name = frappe.scrub("{0}_{1}_{2}_{3}.zip".format(company.abbr,month,year,
                                    reminder_stage_name))

    pdf_file_name = frappe.scrub("{0}_{1}_{2}_{3}.pdf".format(customer_name,month,year,
                                            reminder_stage_name))
    # This is where the error occurs
    pdf_file_content = frappe.get_print(doctype="Sales Invoice", name=sales_invoice.name,
                                print_format=reminder_stage_name,as_pdf=True, doc=None)

    folders = [SALES_INVOICE_BASE,str(year),str(month),str(reminder_stage_name)]
    folder_tree = create_folder_tree(folders)

    if not folder_tree['folder_is_available']:
        frappe.log_error(_("""{0} not found in site's private files,  
            {1} was not saved as a file!!""".format(folder_tree['folder_path'],sales_invoice.name)))
        return

    try:
        file_available = frappe.get_doc('File',{'file_name':pdf_file_name,
                            'folder':folder_tree['folder_path']})
        # Constantly update file            
        if not pdf_file_content.strip() == '':
            remove_file(file_available.name, attached_to_doctype="Sales Invoice", 
                                    attached_to_name=sales_invoice.name)
            # delete_file_from_filesystem(file_available)
        else:
            return
    except DoesNotExistError as e:
        pass

    tmp_file = save_file(pdf_file_name,pdf_file_content,"Sales Invoice",sales_invoice.name,
                                        folder=folder_tree['folder_path'],is_private=1)

`

Stack Trace
File "/home/ubuntu/frappe-bench/apps/estate_manager/estate_manager/tasks.py", line 152, in remind_all_customers_of_payment fm.save_sales_invoice_and_reminder_stage(sales_invoice,reminder_stage) File "/home/ubuntu/frappe-bench/apps/estate_manager/estate_manager/file_manager.py", line 64, in save_sales_invoice_and_reminder_stage print_format=reminder_stage.print_format,as_pdf=True, doc=None) File "/home/ubuntu/frappe-bench/apps/frappe/frappe/__init__.py", line 1183, in get_print return get_pdf(html, output = output) File "/home/ubuntu/frappe-bench/apps/frappe/frappe/utils/pdf.py", line 17, in get_pdf pdfkit.from_string(html, fname, options=options or {}) File "/home/ubuntu/frappe-bench/env/src/pdfkit/pdfkit/api.py", line 66, in from_string configuration=configuration) File "/home/ubuntu/frappe-bench/env/src/pdfkit/pdfkit/pdfkit.py", line 38, in __init__ self.configuration = (Configuration() if configuration is None File "/home/ubuntu/frappe-bench/env/src/pdfkit/pdfkit/configuration.py", line 18, in __init__ ['which', 'wkhtmltopdf'], stdout=subprocess.PIPE).communicate()[0].strip() File "/usr/lib/python2.7/subprocess.py", line 710, in __init__ errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1223, in _execute_child self.pid = os.fork() OSError: [Errno 12] Cannot allocate memory

Please help!
Thanks.

Hi, how much memory does your AWS instance have? Sounds like the generator is running out of memory.

Hi cattmy,
thanks for the reply,

Total memory is 2GB (t2.small), running top command on it while working shows about 1.4GB used, but this quickly increases just before the error.

Thanks.

For 3000 pdfs, I’m pretty sure you are running out of memory. I’d recommend upping the RAM or making a swap file on your server (not recommended for SSD servers but it will still work in most cases).

Thanks so much… I’ll work on it

@bomsy
Did you get any issue in using ERPNext?
We got sometime same issue while generating pdf or using ERP
OSError: [Errno 12] Cannot allocate memory

OR

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x1387681e3ac1 <JS Object>
    1: registerBinding [/home/frappe/clinic/frappe-bench/node_modules/babel-traverse/lib/scope/index.js:~544] [pc=0x234cd3575181] (this=0x2491521103c1 <a Scope with map 0x1097ce32c169>,kind=0x803462d68c9 <String[3]: var>,path=0x249152113d21 <a NodePath with map 0x1097ce32cab1>)
    2: registerDeclaration [/home/frappe/clinic/frappe-bench/node_modules/babel-traverse/lib/scope/index.js:~475] [pc=...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - process out of memory

We run below command to fix it

sudo npm install -g increase-memory-limit