# Fail to load large OBJ

**URL:** <https://forum.babylonjs.com/t/fail-to-load-large-obj/55856>\
**Category:** Bugs\
**Tags:** loaders, obj\
**Created:** [January 8, 2025, 2:36pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856 "2025-01-08T14:36:18Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [January 8, 2025, 2:36pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/1 "2025-01-08T14:36:18Z")

</div>

Hi, I’m trying to load a large obj file (1.3GB) using [https://sandbox.babylonjs.com](https://sandbox.babylonjs.com) and it fails without any error message.  
This file is valid as it loads correctly in paraview. Below are the file details:

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/5/b/5b6336255ebea95f78a0f06268ca0f53ac49ab09.png)  
Am I doing something wrong ?  
File can be found here: [Ferrari Roma Spider.obj - Google Drive](https://drive.google.com/file/d/1vwwqsAI-cgVNlXyshhR4GxuM9pK-Shjd/view?usp=drive_link)  
Regards

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [January 8, 2025, 5:51pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/2 "2025-01-08T17:51:35Z")

</div>

1.3BG will go above the 2GB of ram we are constrained to by the browser when unfolding data.

One approach could be to compress the glb with ktx and draco

---

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [January 9, 2025, 2:39am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/3 "2025-01-09T02:39:57Z")

</div>

Seems too big for a string, any luck with parsing in binary, or [`TextDecoderStream`](https://developer.mozilla.org/en-US/docs/Web/API/TextDecoderStream)?

---

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [January 10, 2025, 8:42am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/4 "2025-01-10T08:42:50Z")

</div>

After reviewing the OBJFileLoader code, it indeed receives a string containing all the file’s data. This will never work for the large files we want to load.

We’ll try to code an alternative loader that creates the different instances as the file is read using a [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).

The most challenging part will be splitting `SolidParser.parse` into several functions, as it expects to receive a complete array, whereas we will pass it chunks instead.

---

<div class="post-metadata">

**Author:** ![roland](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/roland/32/38940_2.png) [@roland](https://forum.babylonjs.com/u/roland)\
**Post date:** [January 10, 2025, 1:00pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/5 "2025-01-10T13:00:47Z")

</div>

I did a few pull requests on the OBJFileLoader so I got quite familiar with the code. I’m pretty sure

> [@Jonathan\_Lafite](#):
>
> The most challenging part will be splitting

this will be daaamn chalenging!

Wouldn’t it be a better option to split the mesh/meshes from the one big OBJ file into multiple meshes/files and load them piece by piece?

---

<div class="post-metadata">

**Author:** ![kzhsw](https://avatars.discourse-cdn.com/v4/letter/k/848f3c/32.png) [@kzhsw](https://forum.babylonjs.com/u/kzhsw)\
**Post date:** [January 21, 2025, 8:14am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/6 "2025-01-21T08:14:19Z")

</div>

If it’s an option to change the mesh, it should be much faster to use a [gltfpack](https://github.com/zeux/meshoptimizer) tool to convert the obj to a glb.

---

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [January 22, 2025, 7:17am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/7 "2025-01-22T07:17:46Z")

</div>

no it’s not an option unfortunatelly as we want to be able to modify the original file.  
I managed to load 2.7GB obj file extracting the babylon code into my own code and applying a buffered reader (only in firefox as Chrome throws an OutOfMemory exception; but it works fine for smaller files 800MB ~~) ; It also works for obj.gz file. I’m now trying to apply the changes in a branch; once it’s ready a pull request will be created.

---

<div class="post-metadata">

**Author:** ![danilogiulio](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/danilogiulio/32/44808_2.png) [@danilogiulio](https://forum.babylonjs.com/u/danilogiulio)\
**Post date:** [January 27, 2025, 6:15am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/8 "2025-01-27T06:15:58Z")

</div>

Hi, any update about this? Your solution now works in Chrome?

---

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [January 27, 2025, 2:48pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/9 "2025-01-27T14:48:59Z")

</div>

No, it’s a Chrome memory limitation. You can find plenty of discussions about this issue online.  
It works fine in Firefox, though.

 ![image](https://us1.discourse-cdn.com/flex024/uploads/babylonjs/original/3X/f/1/f16379d1e2fe8046a824da3f13bfc0af9b014713.png)  
Currently, I’m migrating the code to the Babylon.js `ObjReader` class. However, it won’t be used as the default for the plugin mechanism because the file reading (and all file handling, as far as I understand) is done higher up in the stack, not directly within the class. As a result, we only retrieve a massive string, which makes object creation impossible.

This is why I’m implementing a separate method. Hopefully, Babylon.js expert architects can review this and decide on the best approach. However, making significant changes to the global fetch/read file mechanism is too large a development effort for me to tackle alone.

---

<div class="post-metadata">

**Author:** ![Deltakosh](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/deltakosh/32/26635_2.png) [@Deltakosh](https://forum.babylonjs.com/u/Deltakosh)\
**Post date:** [January 27, 2025, 4:36pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/10 "2025-01-27T16:36:27Z")

</div>

Sorry I missed what we should review? can you share more?

---

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [January 28, 2025, 7:49am UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/11 "2025-01-28T07:49:07Z")

</div>

My pull request once I finished to code and see if you want to integrate this OBJ reading as default.

---

<div class="post-metadata">

**Author:** ![danilogiulio](https://sea2.discourse-cdn.com/flex024/user_avatar/forum.babylonjs.com/danilogiulio/32/44808_2.png) [@danilogiulio](https://forum.babylonjs.com/u/danilogiulio)\
**Post date:** [February 14, 2025, 2:20pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/12 "2025-02-14T14:20:05Z")

</div>

Sure, but I need to run the canva on a large machine calling headless Chromium via Puppeteer, thus increasing the memory size. Removing the string limit from BabylonJS (not passing as a string) will let the DevOps define the correct boundaries. In any case, in this moment it does not work with larger files and the user does not get any feedback when the file is too large

---

<div class="post-metadata">

**Author:** ![Jonathan\_Lafite](https://avatars.discourse-cdn.com/v4/letter/j/ecccb3/32.png) [@Jonathan\_Lafite](https://forum.babylonjs.com/u/Jonathan_Lafite)\
**Post date:** [March 11, 2025, 1:24pm UTC](https://forum.babylonjs.com/t/fail-to-load-large-obj/55856/13 "2025-03-11T13:24:01Z")

</div>

here is the pull request

> <https://github.com/BabylonJS/Babylon.js/pull/16271>
>
> This pull request introduces support for loading and exporting large OBJ files w…ithout requiring the entire file to be loaded into memory as a single string.
> 
> \*\*Loading Enhancements\*\*
> The default behavior remains unchanged when using BABYLON.SceneLoader, ensuring full backward compatibility.
> 
> However, SceneLoader still fetches the entire file, as I could not find a way to prevent this.
> 
> To leverage an incremental reading and building mechanism, the OBJFileLoader class should be used directly, importing meshes without the data parameter:
> 
> \`\`\`
> const objLoader = new BABYLON.OBJFileLoader();
> const { meshes: newMeshes } = await objLoader.importMeshAsync(null, scene, null, "https://file.obj");
> \`\`\`
> This new loading mechanism supports both .obj and .obj.gz files, allowing seamless handling of compressed OBJ files.
> 
> \*\*Parsing Fixes\*\*
> Fixed an issue where some OBJ files with multiple space-separated values (e.g., f 1 4 5) were incorrectly parsed.
> The new behavior correctly normalizes them to f 1 4 5, addressing a case that was not handled by the existing solidParser string manipulation methods.
> 
> 
> \*\*Exporting Changes (Breaking Change)\*\*
> The export method has been modified to return an iterator instead of a full OBJ string.
> 
> This change aligns with the new incremental approach, allowing the data to be processed in chunks instead of requiring full memory allocation.
> 
> The new export method is not backward-compatible but enables efficient writing via a stream writer to output the data progressively to a file or another destination.
> 
> For those who still need the full OBJ as a string, it can easily be converted using:
> 
> 
> \`const obj = \[...BABYLON.OBJExport.OBJ(meshes)\].join("\\n");\`
